2014-06-23 14 views
0

J'ai un modèle User, un modèle Recipe et un modèle Cookbook.Laravel 4 chargement impatient

Un utilisateur peut posséder plusieurs recettes. (Recette utilisateur -UneToMany)

Un utilisateur a un seul livre de recettes. (Cookbook utilisateur-OneToOne)

Les recettes dont un utilisateur est propriétaire appartiennent à son livre de cuisine. Une recette peut appartenir à de nombreux livres de recettes. (Partage de recettes) (Livre de recettes -ManyToMany- Recette)

De nombreux utilisateurs peuvent aimer beaucoup de recettes. (Recette -ManyToMany-)

De nombreux utilisateurs peuvent suivre plusieurs livres de recettes. (User -ManyToMany- livre de recettes)

Un utilisateur peut avoir beaucoup d'amis qui sont des utilisateurs (User -OneToMany- utilisateur)


Ce que je veux faire est des recettes de charge pour l'utilisateur actuellement connecté dans l'utilisateur.

Je veux charger les recettes appartenant à ses amis et les recettes de tous les livres de cuisine l'utilisateur connecté suit.


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'); 
    } 
} 

Ce que je fait est la suivante:

$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); 
    } 
} 

Mais cette méthode exécuterait beaucoup de requêtes SQL. Comment puis-je utiliser le chargement rapide pour réduire le nombre de requêtes?

Répondre

1

Que diriez-vous

$user = Auth::user(); 
$recipesFriends = $user->friends()->with('friends.recipes')->get(); 
$recipesCookbooks = $user->with('followedCookbooks')->with('followedCookbooks.recipes')->get(); 

Si vous voulez aller un peu plus loin, vous pouvez jeter un oeil à cette réponse: How to list out all items in a nested table in Laravel

+0

J'ai utilisé un profileur pour vérifier les requêtes en cours d'exécution. La deuxième ligne de '$ recipesFriends' comportait 4 requêtes dont l'une était' select * from users'. Je ne voudrais jamais que cette requête s'exécute parce qu'elle retournerait un énorme ensemble de données quand il y a beaucoup d'utilisateurs enregistrés. Je modifié votre méthode et un peu utilisé: '$ recipesFriends = $ user-> amis() -> avec ('friends.recipes') -> get();' Cela a éliminé la 'select * de la requête des utilisateurs. Merci! –

+0

Editera ma réponse en conséquence! –

0

Vous pouvez essayer ceci:

$userData = Auth::user()->load('cookbook.recipes') 
         ->load('friends.cookbook.recipes'); 

Si vous voulez pour charger des recettes d'amis dans une variable différente, alors vous pouvez essayer ceci:

$userData = Auth::user()->load('cookbook.recipes') 
         ->load('friends.cookbook.recipes'); 
$friendsData = $userData->friends;