Search code examples
laraveleloquent-relationship

I can't retrieve data from the related table(model) in Laravel6


I can't retrieve data from the related table.

There are 3 models(tables).

  • User
  • Chirp (has 'user_id' as foreign key)
  • Click (has 'chirp_id' as foreign key)

then I want to retrieve User & Click's data from Chirp model. So I wrote:

Chirp.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Chirp extends Model
{
    public $timestamps = false;

    protected $guarded = [];

    public function user()
    {
        return $this->belongsTo('App\User');
    }

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

HomeController.php

class HomeController extends Controller
{

    public function index()
    {
        $chirps = Chirp::with(['user','clicks'])
        ->orderBy('posted_at', 'desc')
        ->get();

        return view('home', ['chirps' => $chirps]);
    }
}

home.blade.php

@foreach($chirps as $chirp)
<div>
    <div>by
    <b>{{ $chirp->user->name }}</b>
        on
        <small>{{ $chirp->posted_at }}</small>
    </div>

    <div>
        <p>{{ $chirp->text }}</p>
        <p>{{ $chirp->click->ip_address }}</p>
    </div>
</div>
@endforeach

at home.blade.php, {{ $chirp->click->ip_address }} can't be retrieved and get error "Facade\Ignition\Exceptions\ViewException Trying to get property 'ip_address' of non-object"

However, if I delete it, I can retrieve {{ $chirp->user->name }} properly.

Why can't I retrieve Click model from Chirp model, While I can retrieve User model from Chirp model?

Thank you.


Solution

  • You need to loop over your clicks as well:

    @foreach($chirps as $chirp)
    <div>
        <div>by
        <b>{{ $chirp->user->name }}</b>
            on
            <small>{{ $chirp->posted_at }}</small>
        </div>
    
        @foreach($chirp->clicks as $click)
            <div>
                <p>{{ $chirp->text }}</p>
                <p>{{ $click->ip_address }}</p>
            </div>
        @endforeach
    </div>
    @endforeach