在 Laravel Eloquent 中获取和过滤关系

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28436167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:53:35  来源:igfitidea点击:

Fetching and filtering relations in Laravel Eloquent

phpsqllaravelormeloquent

提问by Rafael Bugajewski

I have the following models in Eloquent: groups, threads, comments and users. I want to find all comments in a specific group from a specific user.

我在 Eloquent 中有以下模型:组、线程、评论和用户。我想从特定用户中查找特定组中的所有评论。

This is my current approach:

这是我目前的方法:

$group->threads->each(function ($thread) use ($user_id)
{
  $user_comments = $thread->comments->filter(function ($comment) use ($user_id)
  {
    return $comment->owner_id == $id;
  });
});

This looks ugly as hell, is probably slow as hell, and I just want to get rid of it. What is the fastest and most elegant way in Eloquent to get to my result set?

这看起来很丑陋,可能很慢,我只想摆脱它。在 Eloquent 中获得我的结果集的最快和最优雅的方式是什么?

采纳答案by Rafael Bugajewski

patricussolution pointed me in the right direction. I cross posted my question to the laracasts Forumand got a lot of help from Jarek Tkaczykwho also frequently visits this site.

帕特里克斯解决方案为我指明了正确的方向。我在laracasts 论坛上交叉发布了我的问题,并从Jarek Tkaczyk那里得到了很多帮助,他也经常访问这个站点。

hasManyThrough()for the Groupmodel is the way to go:

hasManyThrough()因为Group模型是要走的路:

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

There a couple of caveats, though:

不过,有几个警告:

  1. Use the relation object instead of a collection ($group->comments(), NOT$group->comments)
  2. If you use Laravel's soft deletes you can't just change the get()to a delete(), because you'll get an ambiguity error for the column updated_at. You can't prefix it either, it's just how Eloquent works.
  1. 使用关系对象而不是集合 ( $group->comments(), NOT$group->comments)
  2. 如果您使用 Laravel 的软删除,则不能将 the 更改get()为 a delete(),因为您将收到列的歧义错误updated_at。你也不能给它加前缀,这就是 Eloquent 的工作方式。

If you want to delete all comments from a specific user in a specific group you'll have to do it a little bit differently:

如果您想删除特定组中特定用户的所有评论,则必须以不同的方式进行:

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

ThreadComment::whereIn('id', $commentsToDelete)->delete();

You basically fetch all relevant IDs in the first query and then batch delete them in a second one.

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

回答by patricus

If a grouphasMany threads, and a threadhasMany comments, you can add another relationship to group: grouphasMany commentsthrough threads.

如果一个grouphasManythreads和一个threadhasMany comments,你可以添加另一个关系到组:grouphasManycommentsthreads

On the group:

在小组:

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

Now, you can get the comments in a group by $group->comments;

现在,您可以通过以下方式获取组中的评论 $group->comments;

From here, you can tack on the requirement for the user:

从这里,您可以满足用户的要求:

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

If you want, you can extract the where out into a scope on the Comment.

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