我有4个表在数据库和模型中相关,如下所示:
Users (hasMany(communities), hasMany(comments), hasMany(submissions))
Communities (belongsTo(user), hasMany(submissions))
Submissions (belongsTo(community), belongsTo(user), hasMany(comments))
Comments (belongsTo(user) , belongsTo(submission))
现在。如果我使用关系来获取,比如25个最新的提交,如下:
$submissions = Submission::simplePaginate(25);
在使用foreach遍历结果后,我遇到了76个查询运行。
如果我使用以下
的急切加载$submissions = Submission::with(['user', 'community', 'comments'])->simplePaginate(25);
我遇到了4个最佳查询(我认为)。
现在,我的问题是,在社区上,我有一个名为active的数据库字段,它接受一个活动社区1,0表示非活动社区。您可能已经猜到,之前的查询会返回所有内容,包括非活动社区。 p>
我考虑过急切加载限制,所以我使用了以下内容:
$submissions = Submission::with([
'community' => function($query) {
$query->active();
}
]
)->with(['user', 'comments'])->simplePaginate(25);
这仍然可以完成4个查询,但现在我遇到了另一个问题。此方法过滤非活动社区,但仍会加载帖子,用户和评论。现在我留下了一个结果,我从不活跃的社区获得了帖子。
最后,我在阅读本社区时尝试了以下内容:
$submissions = Submission::whereHas(
'community', function($query) {
$query->active();
}
)->with(['user', 'comments'])->simplePaginate(20);
因此,我使用了 - > whereHas(),而不是使用 - > with()。但是,虽然这会产生正确的结果,即它只给我来自活动社区的帖子,评论和用户,但现在根据我从Laravel Debugbar获得的反馈,它在23个查询中执行此操作。
这是正常的吗?这是我通过Eloquent执行此操作的唯一方法,而无需使用连接编写自定义查询吗?我是不是吹了23个问题?
非常感谢任何帮助。
答案 0 :(得分:1)
您的问题是active()
范围正在为您检索的每个社区运行查询,在您的情况下为20.
要优化此功能,您可以在Submission
模型中建立一个特定关系,您可以主动过滤活动社区。 p>
// Submission model
public function activeCommunities (){
return $this->hasMany(Community::class)->whereActive(true);
}
现在您的查询如下:
$submissions = Submission::with(['user', 'comments', 'activeCommunities])
->simplePaginate(25);
我认为这应该执行4个查询。
希望这会对你有所帮助。
答案 1 :(得分:0)
所以,经过一段时间的修补,我找到了一个解决方案,但我还是不确定。我发布这个以供将来参考,因为它解决了我的问题。我使用的代码如下
$submissions = Submission::whereHas(
'community', function($query) {
$query->where('is_active', true);
}
)->with(['user', 'community'])->withCount('comments')
->paginate(25);
所以,我尝试使用whereHas()
在实际急切加载community
模型之前检查模型是否存在,如果这有意义的话?它似乎得到了我想要的结果,因为我现在执行总共4个查询来获取所有提交,以及相关信息,过滤非活动社区。 p>