我试图通过约束来获得Eager-Loading嵌套关系。每个人似乎都给出了热切加载嵌套关系的相同示例:
$users = User::with('posts.comments')->get();
我想要做的是获取与给定ID的帖子相关的所有用户。但与此同时,我也希望得到与该帖子相关的评论。
在4.1中,我要实现后者,我能做到:
$comments = Comment::whereHas('post', function($query) { $query->whereId(1); })->get();
有没有办法结合这两个并约束嵌套关系?
答案 0 :(得分:8)
实际上发现它比思想简单得多。
鉴于这些模型:
class User extends \Eloquent {
public function posts()
{
return $this->hasMany('Post');
}
public function comments()
{
return $this->hasManyThrough('Comment', 'Post');
}
}
class Post extends \Eloquent {
public function user()
{
return $this->belongsTo('User');
}
public function comments()
{
return $this->hasMany('Comment');
}
}
class Comment extends \Eloquent {
public function post()
{
return $this->belongsTo('Post');
}
}
然后我们可以获取具有给定帖子的用户:
$userId = 2; $postId = 5;
$user = User::with(['comments' => function($q) use($postId) { $q->where('post_id', $postId); }])->find($userId);
使用get()时这不起作用,因为它不会将用户限制为仅与给定帖子相关的用户。但这没关系,因为我们只对post_id $ postId的一篇文章感兴趣。由于帖子属于一个且只有一个用户,我们不必担心其他用户。因此,我们可以使用find()或first()来获得实际结果。
此外,'中间'关系即'post'会自动返回,我们可以通过执行以下操作来获取它,而无需使用前面答案中建议的额外'with':
var_dump($user->posts);
答案 1 :(得分:7)
如果模型中的关系正确,您可以这样做:
$user = User::with('posts.comments')->get();
您可以根据需要添加任意数量的关系(或内存限制;)。
它也适用于数据透视表。
答案 2 :(得分:3)
在User-> Post-> Comment的背景下很难实现这一点,但如果适合你,你可以从Post开始轻松实现这一点:
Post::with('users')->with('comments')->find(1);
因为它会加载所有用户以及与给定帖子相关的所有评论。
- 编辑:不要相信第一句话,它就像这样简单:
// $id of the post you want
User::with(['comments' => function ($q) { // this is hasManyThrough relation
$q->where('post_id',$id); // comments only related to given post
}])->with(['posts' => function ($q) {
$q->whereId($id); // here we load only the post you want
}])->whereHas('posts', function ($q) {
$q->whereId(1); // here we filter users by the post
})->get();
请注意,Laravel会运行3个查询来完成它