dangelsaurus
dangelsaurus

Reputation: 7552

Laravel Eloquent how to return one to many to many collection

Is it possible to get an eloquent relation based on a One->Many->Many relationship? In the below example, I would want to get all of the gallery_votes for a given user.

users
+----+---------------+
| id |  user_name    |
+----+---------------+
|  1 | bob           |
|  2 | sam           |
+----+---------------+

galleries
+----+---------------+-----------+
| id |  gallery_name |  user_id  |
+----+---------------+-----------+
|  1 | Alaska Pics   |        1  |
|  2 | Texas Pics    |        1  |
|  3 | California    |        2  |
|  4 | Cars          |        2  |
+----+---------------+-----------+

gallery_votes
+----+---------------+--------+
| id |  gallery_id   |  vote  |
+----+---------------+--------+
|  1 |           1   |     1  |
|  2 |           1   |     1  |
|  3 |           1   |     1  |
|  4 |           2   |     1  |
+----+---------------+--------+

The relationships are setup as follows.

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {{
    ...
    public function galleries()
    {
        return $this->hasMany('App\Gallery');
    }
}

and

class Gallery extends Model {
    ....
    public function votes()
    {
        return $this->hasMany('App\GalleryVote');
    }

}

$user->galleries returns a collection of associated galleries, so that works correctly. and $gallery->votes returns a collection of associate votes, so that also works correctly. But $user->galleries->votes gives

Undefined property: Illuminate\Database\Eloquent\Collection::$votes on line 1

Is what I'm trying to do even possible with straight Laravel? Or do I need to write the SQL directly?

Upvotes: 2

Views: 1932

Answers (1)

Sh1d0w
Sh1d0w

Reputation: 9520

The "has many through" relation provides a convenient short-cut for accessing distant relations via an intermediate relation.

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {{
    ...
    public function galleries()
    {
        return $this->hasMany('App\Gallery');
    }

    public function votes() 
    {
        return $this->hasManyThrough('App\GalleryVote', 'App\Gallery');
    }
}

Now $user->votes will return all votes for that user. Remember you need to create the GalleryVote eloquent model as well.

You can read more about that type of relation, as well as some example usage in the documentation.

Upvotes: 2

Related Questions