Reputation: 835
I have a User
model, a Recipe
model, and a Cookbook
model.
A User can 'own' many recipes. (User -OneToMany- Recipe)
A user has 'only one' Cookbook. (User -OneToOne- Cookbook)
Recipes that a user owns belong to his Cookbook. One Recipe can belong to many Cookbook. (Recipe sharing) (Cookbook -ManyToMany- Recipe)
Many Users may LIKE Many Recipe. (User -ManyToMany- Recipe)
Many Users can follow Many Cookbook. (User -ManyToMany- Cookbook)
One User can have many friends who are Users (User -OneToMany- User)
What I want to do is load recipes for the currently logged in user.
I want to load the recipes owned by his friends and the recipes of all the cookbooks the logged in user is following.
class User extends Eloquent {
public function friends() {
return $this->belongsToMany('User', 'user_friends', 'user_id', 'friend_id');
}
public function cookbook() {
return $this->hasOne('Cookbook', 'owner_id', 'id');
}
public function recipes() {
return $this->hasMany('Recipe', 'owner_id', 'id');
}
public function followedCookbooks() {
return $this->belongsToMany('Cookbook','cb_followers', 'follower_id', 'cb_id');
}
}
class Recipe extends Eloquent() {
public function owner() {
return $this->belongsTo('User', 'owner_id', 'id');
}
public function cookbooks() {
return $this->belongsToMany('Cookbook', 'cb_recipes', 'recipe_id', 'cb_id');
}
}
class Cookbook extends Eloquent() {
public function owner() {
return $this->belongsTo('User', 'owner_id', 'id');
}
public function recipes() {
return $this->belongsToMany('Recipe', 'cookbooks_recipes', 'cookbook_id', 'recipe_id');
}
public function followers() {
return $this->belongsToMany('User', 'cb_followers', 'cb_id', 'follower_id');
}
}
What I did is this:
$user = Auth::user();
$friends = $user->friends();
$cookbooks = $user->followedCookbooks();
$recipes = array();
foreach($friends as $friend) {
$recipe = $friend->recipes();
array_push($recipes, $recipe);
}
foreach($cookbooks as $cookbook) {
$cbRecipes = $cookbook->recipes()
foreach($cbRecipes as $cbRecipe) {
array_push($recipes, $cbRecipe);
}
}
But this method would run a lot of SQL queries. How can I use eager loading to reduce the number of queries?
Upvotes: 0
Views: 74
Reputation: 1608
How about
$user = Auth::user();
$recipesFriends = $user->friends()->with('friends.recipes')->get();
$recipesCookbooks = $user->with('followedCookbooks')->with('followedCookbooks.recipes')->get();
If you want to go a bit further you can take a look at this answer: How to list out all items in a nested table in Laravel
Upvotes: 1
Reputation: 146191
You may try this:
$userData = Auth::user()->load('cookbook.recipes')
->load('friends.cookbook.recipes');
If you want to load friends recipes in a different variable then you may try this:
$userData = Auth::user()->load('cookbook.recipes')
->load('friends.cookbook.recipes');
$friendsData = $userData->friends;
Upvotes: 0