I\'m quite new to Laravel and I\'m trying to figure out how to properly work with Eloquent so far so good, but I\'m stuck in something I want to do:
I have 3 tables in a
Based on the picture(ie your tables) you sent food_group does not have direct relationship with the portions so you can't chain food_group with portion like this
App\FoodGroup::with('portion.foods')
it should rather be (that is why you getting BadMethodCallException in Builder::portions())
App\FoodGroup::with('foods.portion')
because foodgroup has many foods and foods has many portion. so you can try something like this
App\FoodGroup::with(['foods.portion'=>function($q){
$q->orderBy('id')
}])->get();
Your expected JSON shows foods
as a child of portions
. In order to do this, you need to setup this relationship.
On your Portion
model, you need to setup the following relationship:
public function foods() {
return $this->hasMany(Food::class);
}
With this relationship setup, you can now get your data like this:
$categories = App\FoodGroup::with('portions.foods')->get();
This will load your food groups, then it will load the portions into the food groups, and then it will load the foods into the portions.
I may have slightly misread your question. I assumed you had a portions
relationship defined on \App\FoodGroup
. If not, you can add this like so:
FoodGroup:
public function portions() {
// the second parameter is the name of the pivot table.
// in this case, your foods table connects your portions and food groups.
return $this->belongsToMany(Portion::class, 'foods')->distinct();
}
This solution is a little hacky because it is treating the foods
table as a pivot table, though it wasn't specifically designed for that. Because of this, there are multiple entries in the foods
table that contain the same key pair values, and this is why you're getting duplicate related models.
If you throw a distinct()
onto the relationship, this should take care of the issue, as it will eliminate the duplicates created from the inner join. The code above has been modified.