我在Eloquent中有以下模型:组,线程,评论和用户。我想查找特定用户在特定组中的所有评论。
这是我目前的方法:
$group->threads->each(function ($thread) use ($user_id)
{
$user_comments = $thread->comments->filter(function ($comment) use ($user_id)
{
return $comment->owner_id == $id;
});
});
这看起来丑陋如地狱,可能慢如地狱,我只想摆脱它。在 Eloquent 中,访问我的结果集的最快、最优雅的方式是什么?
如果一个group
有很多threads
,而一个thread
有很多comments
,你可以向组添加另一个关系:group
有很多comments
到threads
。
在组中:
public function comments() {
return $this->hasManyThrough('Comment', 'Thread');
}
现在,您可以按$group->comments;
在组中获取评论
从这里,您可以满足用户的要求:
$user_comments = $group->comments()->where('owner_id', $user_id)->get();
如果需要,您可以将 where 提取到注释的范围中。
patricus解决方案为我指明了正确的方向。我把我的问题交叉发布到laracasts论坛,并从Jarek Tkaczyk那里得到了很多帮助,他也经常访问这个网站。
Group
模型的hasManyThrough()
是要走的路:
public function comments()
{
return $this->hasManyThrough('ThreadComment', 'Thread');
}
不过,有几个警告:
- 使用关系对象而不是集合(
$group->comments()
,而不是$group->comments
( - 如果你使用Laravel的软删除,你不能只是将
get()
更改为delete()
,因为你会收到列updated_at
的歧义错误。你也不能给它加上前缀,这就是 Eloquent 的工作方式。
如果你想删除特定组中特定用户的所有评论,你必须采取一些不同的做法:
$commentsToDelete = $group->comments()
->where('threads_comments.owner_id', $id)
->select('threads_comments.id')
->lists('id');
ThreadComment::whereIn('id', $commentsToDelete)->delete();
您基本上在第一个查询中获取所有相关 ID,然后在第二个查询中批量删除它们。