Laravel集合基于嵌套关系字段值的预先加载

时间:2014-03-27 23:38:39

标签: laravel-4 eager-loading

我正在尝试返回一个Laravel集合对象,该对象具有关系,其中生成的集合基于嵌套条件(即嵌套模型的字段值)。所以它看起来像这样:

  

用户 - >类别 - >发布 - >评论where comment.active == 1

在这种情况下,我希望结果包含注释处于活动状态的所有特定用户的categories => posts => comments。如果它处于活动状态,它将嵌套在适当的层次结构中(Category->Post->Comment)。如果评论未激活,则任何相关帖子和可能的类别(如果没有其他帖子包含有效评论)都不应该显示在集合中。

我尝试通过with()load()filter()加载,但没有运气。他们将继续加载与空评论关系的关系。寻找关于在哪里研究的指导:加入?过滤器?有嵌套的高级人员?


一次尝试:

$user->categories->filter(function($category) {
    return $category->isActive();
});

在我的模型中,我已正确设置所有关系,除此之外,我还设置了isActive(),如下所示:

// Category model

public function isActive() {

    $active = $this->posts->filter(function($post) {
        return $post->isActive();
    }

}

// Post model

public function isActive() {

    return (boolean) $this->comments()->where('active', 1)->count();

}

这可以按预期工作,但它还包括急切加载的嵌套关系,其中注释的活动字段为0.显然,我这样做是错误的,但会欣赏任何方向。


另一次尝试:

User::with(['categories.posts.comments' => function($q) {
    $q->where('active', 1);
}])->find(1);

不幸的是,这也会加载没有有效评论的关系(类别和帖子)。用'categories.posts.isActive'替换关系也不起作用。

1 个答案:

答案 0 :(得分:3)

仍然令人困惑,因为您没有提供足够的代码,但您可以尝试这样的方法来让所有用户使用嵌套categories.posts.comments而无条件:

$users = User::with('categories.posts.comments')->get();

但即使你没有任何意见,它也能给你所有的东西,但是为了增加条件,你可以尝试这样的事情:

// It should return all user models with `categories - posts - active comments`
$users = User::with('categories.posts.activeComments')->get();

Post型号:

public function activeComments() {
    return $this->hasMany('Comment')->where('active', 1);
}

您还可以使用以下约束添加更多过滤器:

$users = User::with(array('categories.posts.activeComments' => function($query){
    $query->whereNull('comments.deleted_at');
}))->get();

但我不确定,对你的人际关系不够了解,所以只是给了你一个主意。