5

When i try echo the value i receive an exeception. I check the collection with dd() and is not null.

My Models:

Cliente:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Cliente extends Model
{
    protected $table = 'clientes';

    public function ordens() {
        return $this->hasMany('App\OrdemServico','cliente_id');
    }
}

OrdemServico:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class OrdemServico extends Model
{
    protected $table = 'ordens_servico';

    public function clientes() {
        return $this->belongsTo('App\Cliente','id');
    }
}

OrdemServicoController:

public function index()
{

    $ordens = OrdemServico::with('clientes')->get();

    return view('home',compact('ordens'));

}

Part View Home:

             <table class="table">
                    <thead>
                    <tr>
                        <th scope="col">#</th>
                        <th scope="col">Nome Cliente</th>
                        <th scope="col">Modelo</th>
                        <th scope="col">Status O.S</th>
                    </tr>
                    </thead>
                @foreach($ordens as $ordem)
                    <?php //dd($ordem->clientes->nome); ?>
                    <tr>
                        <th scope="row"></th>
                        <td>{{$ordem->id}}</td>
                        <td>{{$ordem->clientes->nome}}</td>
                        <td></td>
                        <td></td>
                        <td><button class="btn btn-outline-primary" onclick="location.href='{{ route('ordem_servico.show',1) }}'">Mostrar mais</button></td>
                    </tr>
                @endforeach

                    </tbody>
                </table>

When i

<?php dd($ordem->clientes->nome); ?>

I receive:

dd() return

But when i try echo the value, i receive a execpetion.

dd() of $ordem.

https://gist.github.com/vgoncalves13/8140a7a1bf2cb85fe4d16da20ea34acc

  • Do all the `$ordem`'s have `clientes`? You're `dd`'ing the first item in the loop, but what if the 2nd doesn't have `clientes`? You'd see that exception then. – Brian Lee Jun 30 '18 at 23:45
  • 1
    Use like this: `optional($ordem->clientes)->nome` in case of empty `$ordem->clientes` – Mustafa Akçakaya Jun 30 '18 at 23:52
  • How many clientes does a order have? If it has more than one you should user `$oderm->clientes->first()->name` or loop through all clientes. – Renoir Reis Jun 30 '18 at 23:53
  • Thanks guys. select * from `ordens_servico` select * from `clientes` where `clientes`.`id` in ('1', '2') The eager-loading are trying find client with id 1 and 2. But i have 2 $orders for the same $client. Using the optional, The name is echoed, but the second not. I'll figure out how fix this. Thanks again. You gave me a north, now. – Victor Gonçalves Jun 30 '18 at 23:59

3 Answers3

1

$ordem->clientes is array, display them like this

     @foreach($ordens as $ordem)
                <?php //dd($ordem->clientes->nome); ?>
        <tr>
            <th scope="row"></th>
            <td>{{$ordem->id}}</td>
            @foreach($ordem->clientes->toArray() as $client)
                <td>{{$client['nome']}}</td>
            @endforeach
            <td></td>
            <td></td>
            <td><button class="btn btn-outline-primary" onclick="location.href='{{ route('ordem_servico.show',1) }}'">Mostrar mais</button></td>
        </tr>
    @endforeach
Hussein
  • 1,143
  • 1
  • 9
  • 16
1

Perhaps your relationship should be called cliente() assuming a order only belongs to one App\Cliente... and you should pass the third argument which is the other_key... you can avoid this type of error by using english (since laravel would search for customer_id and order_id)

Try the following code

namespace App;

use Illuminate\Database\Eloquent\Model;

class Cliente extends Model
{
    protected $table = 'clientes';

    public function ordens() {
        return $this->hasMany('App\OrdemServico','cliente_id');
    }
}

and

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class OrdemServico extends Model
{
    protected $table = 'ordens_servico';

    public function cliente() {
        return $this->belongsTo('App\Cliente', 'id', 'cliente_id');
    }
}

Reference: https://laravel.com/docs/5.6/eloquent-relationships#one-to-many

Renoir Reis
  • 359
  • 4
  • 17
  • Using public function cliente() { return $this->belongsTo('App\Cliente','cliente_id'); }. Laravel selected correctly. Searching only for one client. select * from `clientes` where `clientes`.`id` in ('1') – Victor Gonçalves Jul 01 '18 at 01:07
0

You code is perfect, one of your clientes relation may be empty and you have that code in loop, causing the error. Just add if check should work

<table class="table">
    <thead>
        <tr>
            <th scope="col">#</th>
            <th scope="col">Nome Cliente</th>
            <th scope="col">Modelo</th>
            <th scope="col">Status O.S</th>
        </tr>
    </thead>
        @foreach($ordens as $ordem)
            <?php //dd($ordem->clientes->nome); ?>
            <tr>
                <th scope="row"></th>
                <td>{{$ordem->id}}</td>
                <td>
                    @if ($ordem->clientes)
                        {{$ordem->clientes->nome}}
                    @else
                        'No Client'
                    @endif
                </td>
                <td></td>
                <td></td>
                <td><button class="btn btn-outline-primary" onclick="location.href='{{ route('ordem_servico.show',1) }}'">Mostrar mais</button></td>
            </tr>
        @endforeach
    </tbody>
</table>

Note: Always try to use singular name for belongsTo relationship because it return you one model. For example you should use cliente relationship name instead clientes.

rkj
  • 8,067
  • 2
  • 27
  • 33