Laravel如果后跟嵌套则不限制预加载内部约束'with'
Laravel Eager loading internal constraints are not limited if followed by nested 'with'
这是一个问题和我自己的答案(我偶然想到的解决方案)。 Laravel 文档没有提到这一点,它给我带来了数小时的编程痛苦。
假设我们有 Post 评论和投票(用于评论)。 Laravel 最喜欢的例子。模型和关系是教科书(来自 Laravel 的文档)。 Posts有评论,评论有投票。
所以,
$comments_ids = [1,6,7,22];
Post::where('id', $post_id)
->with(['comments' => function($query) use ($comments_ids) {
$query->whereIn('id', $comments_ids);
}])
->with('comments.votes')
->first();
所以,我应该期待 Post 评论,其中 ID 为 1,6,7,22 并且投票已加载。
但没那么快!我得到所有评论!他们都! ...为什么?
以下是该问题的答案:
因为,我们急于加载评论然后加载投票,投票强制加载所有评论。
这个:
$comments_ids = [1,6,7,22];
Post::where('id', $post_id)
->with(['comments' => function($query) use ($comments_ids) {
$query->whereIn('id', $comments_ids);
}])
->with('comments.votes') //this forces Builder to completely ignore whereIn clause above.
->first();
应该写成:
$comments_ids = [1,6,7,22];
Post::where('id', $post_id)
->with(['comments' => function($query) use ($comments_ids) {
$query->whereIn('id', $comments_ids)
->with('votes'); //eager load votes with filtered comments
}])
->first();
然后您将获得在 $comments_ids 变量中指定 id 的评论。并热切地为他们投票。
这个细微差别引起了很多麻烦。
这是一个问题和我自己的答案(我偶然想到的解决方案)。 Laravel 文档没有提到这一点,它给我带来了数小时的编程痛苦。
假设我们有 Post 评论和投票(用于评论)。 Laravel 最喜欢的例子。模型和关系是教科书(来自 Laravel 的文档)。 Posts有评论,评论有投票。
所以,
$comments_ids = [1,6,7,22];
Post::where('id', $post_id)
->with(['comments' => function($query) use ($comments_ids) {
$query->whereIn('id', $comments_ids);
}])
->with('comments.votes')
->first();
所以,我应该期待 Post 评论,其中 ID 为 1,6,7,22 并且投票已加载。
但没那么快!我得到所有评论!他们都! ...为什么?
以下是该问题的答案:
因为,我们急于加载评论然后加载投票,投票强制加载所有评论。
这个:
$comments_ids = [1,6,7,22];
Post::where('id', $post_id)
->with(['comments' => function($query) use ($comments_ids) {
$query->whereIn('id', $comments_ids);
}])
->with('comments.votes') //this forces Builder to completely ignore whereIn clause above.
->first();
应该写成:
$comments_ids = [1,6,7,22];
Post::where('id', $post_id)
->with(['comments' => function($query) use ($comments_ids) {
$query->whereIn('id', $comments_ids)
->with('votes'); //eager load votes with filtered comments
}])
->first();
然后您将获得在 $comments_ids 变量中指定 id 的评论。并热切地为他们投票。
这个细微差别引起了很多麻烦。