Laravel 4急切加载

时间:2014-06-23 19:50:11

标签: php laravel eager-loading

我有User模型,Recipe模型和Cookbook模型。

用户可以拥有'许多食谱。 (User -OneToMany- Recipe)

用户只有一个'菜谱。 (User -OneToOne- Cookbook)

用户拥有的食谱属于他的食谱。 One Recipe可以属于许多Cookbook。 (食谱分享)(Cookbook -ManyToMany- Recipe)

许多用户可能喜欢很多食谱。 (用户-ManyToMany-食谱)

许多用户可以关注许多Cookbook。 (User -ManyToMany- Cookbook)

一个用户可以拥有许多用户(用户-OneToMany-用户)

的朋友

我想要做的是为当前登录的用户加载配方。

我想加载他朋友拥有的食谱以及登录用户正在关注的所有食谱的食谱。


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

我做的是:

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

但是这种方法会运行很多SQL查询。如何使用预先加载来减少查询次数?

2 个答案:

答案 0 :(得分:1)

怎么样

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

如果您想进一步了解,可以查看以下答案:How to list out all items in a nested table in Laravel

答案 1 :(得分:0)

你可以试试这个:

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

如果您想在其他变量中加载好朋友食谱,那么您可以尝试这样做:

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