I have 3 models: Conference
, Session
and Speaker
. A Conference can have many Sessions and many Sessions can have many Speakers.
conferences
-----------
id
name
sessions
--------
id
conference_id
name
session_speaker
---------------
id
session_id
speaker_id
speakers
--------
id
name
I need to write a method which allows me to get all the Speakers of a particular Conference (so all the Speakers from all the Sessions of that particular Conference).
The following illustrates what I think should work, but it obviously doesn't as I can't chain these together.
class Conference extends Eloquent {
public function speakers() {
return $this->hasMany('Session')->belongsToMany('Speaker');
}
}
I have all the Model-Model relationships setup and working correctly (Conference-Sessions, Session-Speakers) however I can't create the bridge between Conference-Sessions-Speakers. Does anyone know how I can achieve this without writing a large SQL join query?
I think if there was a relationship belongsToManyThrough()
this would work however there isn't.
Thanks in advance!
Unfortunately, the hasManyThrough relation does not work with many to many relationships in between.
What you can do is something like this:
public function speakers() {
$session_ids = Session::where('conference_id', $this->id);
$speaker_ids = DB::table('session_speaker')->whereIn('session_id', $session_ids)->lists('speaker_id');
return Speaker::whereIn('id', $speaker_ids)->get();
}
You probably need to set the variables to array(0)
if no results are found, otherwise the whereIn function will throw an error.
You could also use an Eloquent-only way, but that would probably result in many more database queries, while this one should be fine with only 2 queries being run.
You can then access the speakers with e.g. Conference::find(1)->speakers()
.
Note from 2021: This answer is from back in 2014 and relates to Laravel 4. Nowadays, this apparently does not work anymore. I would encourage you to check the Laravel docs, maybe this problem can now be solved in a better way.