I have the following tables:
lessons
- lessonID
- lessonName
..
sections
- sectionID
- lessonID references lessons.lessonID
..
exercises
- exerciseID
- sectionID references sections.sectionID
..
I have set up the following relations:
Lesson:
public function sections()
{
return $this->hasMany('Section', 'lessonID');
}
Section:
public function lesson() {
return $this->belongsTo('Lesson', 'lessonID');
}
public function exercise() {
return $this->hasOne('Exercise', 'sectionID');
}
Exercise:
public function section() {
return $this->belongsTo('Section', 'sectionID');
}
Now I want to say that a Lesson has many Exercises through Sections, so I tried adding
public function exercises()
{
return $this->hasManyThrough('Exercise', 'Section', 'lessonID', 'sectionID');
}
to the Lessons model and I run
Lesson::with('sections', 'exercises')
gives me an empty array for the exercises. How can I accomplish what I want?
Edit: I'm seeding the Exercise table like so:
<?php
class ExerciseTableSeeder extends Seeder {
public function run()
{
DB::table('exercises')->delete();
Exercise::create(array(
'exerciseID' => 1,
'sectionID' => 2,
...
));
Exercise::create(array(
'exerciseID' => 2,
'sectionID' => 4,
...
));
}
}
?>
Edit 2: Here's my models: http://laravel.io/bin/2Rdl
And here are the query logs: http://laravel.io/bin/vebK
So in short: The Lesson and its Sections are returned fine, but I get an empty array for the Exercises.
After I reported the issue on their Github, I got an embarrassingly simple answer: the request should be Lesson::with('sections.exercises')
instead.
Here lies the problem:
public function exercise() {
return $this->hasOne('Exercise', 'Section');
}
should be:
public function exercise() {
return $this->hasOne('Exercise', 'sectionID');
}
edit:
Your hasManyThrough relation was wrong too. It goes like this:
hasManyThrough('farModel', 'relatedModel', 'keyOnRelatedModel', 'keyOnFarModel')
so correct:
public function exercises()
{
return $this->hasManyThrough('Exercise', 'Section', 'lessonID', 'sectionID');
}
edit: to @clod986 note - hasManyThrough() works just the same for ONE-TO-MANY -> ONE-TO-ONE as long as the latter is hasOne (not belongsTo) relation.
Seems fine to me as you set it up now, after @deczo's help. Probalby you just don't have any related entry, which could be the reason for an empty array
EDIT
Seems that the hasManyThrough
function is not supposed to be used in this situation.
Given that the relations are set correctly (as you confirm in the comments to this answer), the answer is to be found in the documentation. It clearly states
For example, a Country model might have many Posts through a Users model
I believe that the relation for which hasManyThrough
is intended for a ONE-to-ONE + ONE-to-MANY. In your case is ONE-to-MANY + ONE-to-ONE, which might be why it doesn't work.
I would suggest you to report this issue to the github page.