Problems when listing related table data in Laravel 5.3?

1

I'm working with php, laravel 5.3 and myql. After creating everything (Migration, model, controller, View, relationship), is giving me the following error:

  

ErrorException in 1d01653e0e29121ce444ef5c2072fb4d52e5e7db.php line 12:   Trying to get property of non-object (View: C: \ xampp \ htdocs \ Project5_3 \ resources \ views \ products \ index.blade.php)

But when I remove the line from the view

 <p style="color: #069">{{ $produto->categs->nome_cat }}</p>

Only the data in the product table appears. How do I resolve this issue?

Code.

Migration categs

class CreateCategsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categs', function (Blueprint $table) {
            $table->increments('id');
            $table->text('nome_cat');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('categs');
    }
}

Migration products

class CreateProdutosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('produtos', function (Blueprint $table) {

            $table->engine = 'InnoDB';

            $table->increments('id');
            $table->text('nome');
            $table->text('descricao');
            $table->unsignedinteger('categs_id');
            $table->timestamps();

            $table->foreign('categs_id')->references('id')->on('categs');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('produtos');
    }
}

Model categs

namespace App;

use Illuminate\Database\Eloquent\Model;

class categ extends Model
{
    //Relacionamento 1:n Categoria dos produtos

    public function produtos()
    {
        return $this->hasMany('App\produtos');
    }
}

Model products

namespace App;

use Illuminate\Database\Eloquent\Model;

class Produtos extends Model
{
    //
    public function categoria()
    {
        return $this->belongsTo('App\categs');
    }
}

Controller products

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Produtos;

class ProdutosController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $produtos = Produtos::all();
        return view('produtos.index',['todosprodutos'=>$produtos]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('produtos.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'nome' => 'required',
            'descricao' => 'required'
            ]);

        $produtos = new Produtos;
        $produtos->nome = $request->nome;
        $produtos->descricao = $request->descricao;
        $produtos->id_cat = $request->id_cat;
        $produtos->save();

        return redirect('produtos')->with('message', 'Produto gravado com sucesso!');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $produtos = Produtos::find($id);
        if(!$produtos)
            {abort(404);}
        return view('produtos.details')->with('detailpage',$produtos);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $produtos = Produtos::find($id);
        if(!$produtos)
            {abort(404);}
        return view('produtos.edit')->with('detailpage',$produtos);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'nome' => 'required',
            'descricao' => 'required',
        ]);

        $produtos = Produtos::find($id);
        $produtos->nome = $request->nome;
        $produtos->descricao = $request->descricao;
        $produtos->save();
        return redirect('produtos')->with('message', 'Produto actualizado com sucesso!');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $produtos = Produtos::find($id);
        $produtos->delete();
        return redirect('produtos')->with('message', 'Produto excluido com sucesso!');
    }
}

View product - index

@extends('novomaster')
{{ Session::get('message') }}
@section('left-sidebar')
<h1 style=" color: #069">Produtos</h1>
<a class="btn btn-primary" href="produtos/create">Novo Produto</a>
<hr>

    @foreach($todosprodutos as $produto)
    <div class="alert alert-info" style="background-color:#C9DCFC">
        <h2><a href="/produtos/{{ $produto->id }}">{{ $produto->nome }}</a></h2>      
        <p style="color: #FFF">{{  $produto->descricao  }}</p>
        <p style="color: #069">{{ $produto->categs->nome_cat }}</p>
        <br />  


        <form action="/produtos/{{ $produto->id }}" method="POST">
            <input type="hidden" name="_method" value="delete">
            <input type="hidden" name="_token" value="{{ csrf_token() }}">
            <a class="btn btn-small btn-primary" href="/produtos/{{ $produto->id }}/edit"><i class="glyphicon glyphicon-edit"></i></a>

            <button class="btn btn-small btn-danger" type="submit" name="name" value="Apagar"><i class="glyphicon glyphicon-trash"></i></button>

       </form>
    </div> 
   @endforeach
@endsection
    
asked by anonymous 29.07.2017 / 02:40

1 answer

1

No model , since the key name was not default, then you have to configure your model to receive this key in the configuration:

namespace App;

use Illuminate\Database\Eloquent\Model;

class categ extends Model
{
    //Relacionamento 1:n Categoria dos produtos

    public function produtos()
    {
        return $this->hasMany('App\Produtos', 'categs_id', 'id');
    }
}   
namespace App;

use Illuminate\Database\Eloquent\Model;

class Produtos extends Model
{
    //
    public function categoria()
    {
        return $this->belongsTo('App\categ','categs_id', 'id');
    }
}

Now with the key settings and the relationship, the data load for these relationships will work. Another point is to note: because categ if the first letter should be uppercase, ie Categ , and the other model is correct Produtos ? the lack of default causes this confusion in the code, then follow the correct nomenclature all models beginning with the first letter in upper case, example Categoria , Produto , Cliente , etc and do not cut the name also instead of Categ put Categoria , in my view this makes development and maintenance much easier! But, I did what is in your question, these are recommendations.

In the controller method change, as an example below:

public function index()
{
    $produtos = Produtos::with('categoria')->get();
    return view('produtos.index',['todosprodutos'=>$produtos]);
}

where with will load the relation, and in its View change:

<p style="color: #069">{{ $produto->categoria->nome_cat }}</p>

Note: The name that is in the relationship of your model is the same as the name of the method you tried to access.

29.07.2017 / 02:59