代码之家  ›  专栏  ›  技术社区  ›  Rafael Bugajewski

Laravel Eloquent中的获取和过滤关系

  •  2
  • Rafael Bugajewski  · 技术社区  · 9 年前

    我在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 回复  |  直到 9 年前
        1
  •  5
  •   patricus    9 年前

    如果 group 有很多 threads thread 有很多 comments ,可以向组添加另一个关系: 有很多 评论 通过 螺纹 .

    在组上:

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

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

    从这里,您可以确定用户的要求:

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

    如果需要,可以将where提取到Comment的范围中。

        2
  •  2
  •   Community miroxlav    7 年前

    patricus 解决方案为我指明了正确的方向。我将问题交叉发布到 laracasts Forum 得到了很多帮助 Jarek Tkaczyk 他也经常访问这个网站。

    hasManyThrough() 对于 Group 模型是正确的选择:

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

    不过,这里有几个警告:

    1. 使用关系对象而不是集合( $group->comments() , 不是 $group->comments )
    2. 如果您使用Laravels软删除,您不能只更改 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,然后在第二个查询中批量删除它们。