Sergey Harini
Sergey Harini

Reputation: 15

HasMany with belongsToMany relationship

I have 3 models: Persons, Events and Files. A Persons can have many Events and many Events can have many Files.

| persons |
-----------
id
name


| events |
----------
id
person_id
name


| event_file |
--------------
id
event_id
file_id


| files |
---------
id
name

In the Persons model I have this relationship:

public function events()
{
    return $this->hasMany('Events', 'person_id');
}

In the Events model:

public function files()
{
    return $this->belongsToMany('Files', 'event_file', 'event_id', 'file_id');
}

Is it possible to create a relation directly between Persons and Files that translates to something like:

$files = Person::find($id)->events->files;
// OR
$files = Person::find($id)->files;

Thanks!

Upvotes: 0

Views: 351

Answers (3)

TrueStory
TrueStory

Reputation: 439

What about

Person::where('id',$id)->with('events')->with('events.files')->get();

? eagerload that

Upvotes: 0

Jarek Tkaczyk
Jarek Tkaczyk

Reputation: 81187

Like in the comment, it's impossible to setup such relationship with builtin methods of Eloquent. Here's how you can get the files using a bit of trickery:

Person::with(['events.files' => function ($q) use (&$files) {
  $files = $q->get()->unique();
}])->find($id);

Then:

$files; // collection of files related to the Person through collection of his events

Mind that this code will run additional query to get the files, so in the example above:

1 fetch Person
2 fetch Events related to Person
3 fetch Files related to all the Events
4 again fetch Files related to all the Events

Upvotes: 1

klauskpm
klauskpm

Reputation: 3155

You could use "hasManyThrough". On the example bellow, you could see that i want to get the posts, through the users. Just like you want to get files through events.

class Country extends Eloquent {

    public function posts()
    {
        return $this->hasManyThrough('Post', 'User');
    }

}

And you would invoke as:

$country->posts;

Or, as you wish:

Person:find(1)->files;

If you want a better explanation, follow the link to Laravel's own page: http://laravel.com/docs/4.2/eloquent#has-many-through

Upvotes: 0

Related Questions