garethdn
garethdn

Reputation: 12351

Only first() works for nested relationship

I'm having trouble accessing a nested relationship from a collection of models. If I use first() I can access the relationship of that specific model. For example...

public function movie($id)
{
    $member = Movie::find($id)->cast()->first()->person;

    return View::make('movie')->with(array(
        'data' => $member
    ));     
}

In this case echo $data forms a result like {"person_id":"10255","name":"Paul Benedict"}. That's fine but if I try doing something like...

$cast = Movie::find($id)->cast;

return View::make('movie')->with(array(
    'data' => $cast
));

If, in my view, I then try to print out each person like so...

foreach ($data->person as $member) {
    echo $member;
}

I get the following error:

Undefined property: Illuminate\Database\Eloquent\Collection::$person

What exactly am I doing wrong and how do I do it correctly?

Follow on from previous question

Upvotes: 0

Views: 67

Answers (1)

msturdy
msturdy

Reputation: 10794

Long time no speak! :) I'm going to go through this step-by-step (as much for my own understanding)

First, in this case, we take the following steps:

$member = Movie::find($id)->cast()->first()->person;
  1. Movie::find($id)->cast() - here we have a Collection of MovieCast objects.
  2. ->first() - we take the first MovieCast and...
  3. ... ->person - we take the Person object that's linked to the MovieCast object.

Now, we have an instance of the Person object in the $member variable. Maybe he has a name, or some other attributes (created_at, modified_at, age, whatever).

Let's look at the other case:

$cast = Movie::find($id)->cast;

Here we only have a Collection of MovieCast objects in the $cast variable. When we loop over this Collection, we will get back instances of the MovieCast object.

So, we need to loop over these objects like this (in the movie view):

// I've used the same $data variable as you're defining in your Controller.
@foreach($data as $d)

    // each $d is a MovieCast object, so you can access his ->person() method.
    <pre>{{ $d->person->name }}</pre>

@endforeach

The problem is that by running ->person in the foreach, you were running it against the Collection object, which doesn't have a person() method; hence the error!

Does that make sense?

Upvotes: 1

Related Questions