TransWikia.com

Como acessar belongsTo e hasOne na view? - Relacionamento 1 - 1 bidirecional

Stack Overflow em Português Asked by Rafael Blum on December 19, 2021

Estou com projeto com Laravel 6.0 e tem a entidade User e endereço, onde usuário tem 1 endereço, assim como um endereço pertence a 1 usuário (bidirecional).

O problema é que que listar todos endereços e na lista ter a coluna do nome do usuário, até consigo, mas não me parece a melhor forma, então gostaria de auxilio para saber a melhor forma. Segue desenvolvimento:

Model User e Adress:

User

public function address(){
    return $this->hasOne(Adress::class, 'user', 'id');
}

Adress

public function user(){
    return $this->belongsTo(User::class, 'user', 'id');
}

WEb.php:: Rota:

 Route::get('enderecos', 'AdressController@index')->name('adress.list');

AdressController:: Metodo index para listar

public function index()
{
    $users = User::all();
    $adresses = $this->adress->paginate(5);
    return view('adress.index', compact('adresses', 'users'));
}

index.blade.php:: Listagem da view

    <table class="table" id="formCad">
        <tr>
            <td>Id</td>
            <td>Rua</td>
            <td>Numero</td>
            <td>Cidade</td>
            <td>Estado</td>
            <td>Usuário</td>
        </tr>

        @foreach($adresses as $adress)
            <tr>
                <td>{{$adress->id}}</td>
                <td>
                    <a href="{{route('adress.details', ['adress'=>$adress])}}">
                        {{$adress->street}}
                    </a>
                </td>
                <td>{{$adress->number}}</td>
                <td>{{$adress->city}}</td>
                <td>{{$adress->state}}</td>
                <td>
                    @foreach($users as $user)
                        @if($user->id == $adress->user)
                            {{$user->name}}
                        @endif
                    @endforeach
                </td>
            </tr>
        @endforeach
    </table>

Essa é a melhor forma abaixo? Poderiam me explicar ou dicas?

<td>
    @foreach($users as $user)
         @if($user->id == $adress->user)
              {{$user->name}}
          @endif
    @endforeach
</td>

Obrigado!

2 Answers

Você não precisa chamar os dois relacionamentos, basta chamar um

Eu faria assim:

public function index(){
$users = User::with(['address'])->->paginate(5);
return view('adress.index', ['users' => $users]);

}

na Index:

@foreach($users as $user)
<tr>
    <td>{{$adress->id}}</td>
    <td>
        <a href="{{route('adress.details', ['adress'=>$user->adress])}}">
            {{$user->adress->street}}
        </a>
    </td>
    <td>{{$user->adress->number}}</td>
    <td>{{$user->$adress->city}}</td>
    <td>{{$user->$adress->state}}</td>
    <td>
        {{$user->->name}}
    </td>
</tr>
@endforeach

Caso vc queira fazer pelos endereços vc troca e usa o paginate por endereços e troca o relacionamento...

Acho que funfa!

Answered by Luiz Lapetina on December 19, 2021

Você não precisa fazer um loop no array de usuários para saber qual usuário do endereço. A relação que você criou deveria trazer essa informação.

O problema aqui é que você criou no banco de dados a coluna user, e usou esse mesmo nome na relação.

Tente chamar a relação com outro nome, exemplo:

Address.php

public function addressUser(){
    return $this->belongsTo(User::class, 'user', 'id');
}

Dessa forma você terá o campo user que vem do banco e o campo addressUser que será uma relação mapeada ao objeto usuário.

Fazendo isso, tente acessar dessa forma:

@foreach($adresses as $adress)
    <tr>
        <td>{{$adress->id}}</td>
        <td>
            <a href="{{route('adress.details', ['adress'=>$adress])}}">
                {{$adress->street}}
            </a>
        </td>
        <td>{{$adress->number}}</td>
        <td>{{$adress->city}}</td>
        <td>{{$adress->state}}</td>
        <td>
            {{$adress->addressUser->name}}
        </td>
    </tr>
@endforeach

Para as próximas relações, recomendo usar a nomenclatura que o próprio Laravel indica, que é {nome_tabela}_id, ou seja, ao invés de na tabela address você ter um campo user, use um campo chamado user_id.
Dessa forma o Laravel consegue até mesmo fazer o mapeamento automático no BelongsTo, então você só precisaria usar $this->belongsTo(User::class);. E fica melhor também pois você poderá nomear a relação como user, pois não vai ter conflito com os campos originais.

Answered by Phiter on December 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP