在Laravel Eloquent中获取和过滤关系

时间:2015-02-10 16:01:47

标签: php sql laravel orm eloquent

我在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中获取结果集的最快和最优雅的方法是什么?

2 个答案:

答案 0 :(得分:1)

如果group有多个threadsthread有多个comments,您可以向群组添加其他关系:group hasMany comments通过threads

关于小组:

public function comments() {
    return $this->hasManyThrough('Comment', 'Thread');
}

现在,您可以按$group->comments;

在组中收集评论

从这里开始,您可以满足用户的需求:

$user_comments = $group->comments()->where('owner_id', $user_id)->get();

如果需要,您可以在评论中提取范围。

答案 1 :(得分:1)

patricus解决方案指出了我正确的方向。我将问题发布到laracasts Forum并得到Jarek Tkaczyk的大量帮助,他们也经常访问此网站。

对于hasManyThrough()模型,

Group是可行的方法:

public function comments()
{
  return $this->hasManyThrough('ThreadComment', 'Thread');
}

但有几点需要注意:

  1. 使用关系对象代替集合($group->comments() $group->comments
  2. 如果您使用Laravel的软删除功能,则无法将get()更改为delete(),因为您会在列updated_at中出现歧义错误。你也不能加前缀,这就是Eloquent的工作方式。
  3. 如果您要删除特定群组中特定用户的所有评论,则必须采取不同的措施:

    $commentsToDelete = $group->comments()
            ->where('threads_comments.owner_id', $id)
            ->select('threads_comments.id')
            ->lists('id');
    
    ThreadComment::whereIn('id', $commentsToDelete)->delete();
    

    您基本上在第一个查询中获取所有相关ID,然后在第二个查询中批量删除它们。