以一个关联为条件,急切加载 Laravel 中的多个关联
Eager Loading Multiple Associations In Laravel With A Condition On One Association
我一直在尝试快速加载一个论坛模型,但我还需要该论坛的所有讨论区,以及最近的讨论帖和为每个讨论区创建该讨论帖的用户。经过广泛的研究,这是我的方法:
public function show($forum)
{
$forumCol = Forum::with([
'boards' => function($query) {
return $query->with(['threads' => function($query) {
return $query->with('user')->latest()->first();
}])->get();
}
])->where('id', $forum)->first();
return view('forum.forum', ['forum' => $forumCol]);
}
然而,无论我尝试上面的内容有多少种不同的变体,我都无法加载线程或用户。使用 $forum 变量添加页面时。我在论坛和相关版块中获得了一个集合,但线程正在加载为一个空集合(因此我无法加载用户)。
对于这种急切加载,我的语法不正确吗?我已经为此工作了几个小时,非常感谢任何帮助。
谢谢
编辑:
Sandeesh,我也是这么想的,但我已经尝试过了,线程仍然是一个空集合。另外,以防万一你想知道我已经检查了我所有的关系并且它们工作得很好。这是 $forum 集合的屏幕截图:
如果有人好奇我是如何解决这个问题的,请在下面回答。
预加载约束应该 return 查询生成器,而不是集合。你的错误在于 first()
和 get()
。您也不需要使用 return。
public function show($forum)
{
$forumCol = Forum::with(['boards' => function($query) {
$query->with(['threads' => function($query) {
$query->with('user')->latest()->take(1);
}]);
}])->where('id', $forum)->first();
return view('forum.forum', ['forum' => $forumCol]);
}
这花了我很长时间,但我终于找到了答案!经过大量研究,我偶然发现了一个建议采用这种方法的网站:
与你其余模特关系:
public function latestThread()
{
return $this->hasOne('ReadIt\Thread')->latest();
}
然后,我可以像下面这样简单地预加载,而不是对一个关联设置条件:
$forumCol = Forum::with(
'boards',
'boards.latestThread',
'boards.latestThread.user'
)->where('id', $forum)
->first();
当我看到这个时,起初我非常怀疑。我测试了它,但它确实有效。你可以使用hasOne,即使关系是hasMany,它也会得到第一个。现在我不确定为什么你之后能够组织以确保你获得最新的线程,但它有效!
希望对您有所帮助。
我一直在尝试快速加载一个论坛模型,但我还需要该论坛的所有讨论区,以及最近的讨论帖和为每个讨论区创建该讨论帖的用户。经过广泛的研究,这是我的方法:
public function show($forum)
{
$forumCol = Forum::with([
'boards' => function($query) {
return $query->with(['threads' => function($query) {
return $query->with('user')->latest()->first();
}])->get();
}
])->where('id', $forum)->first();
return view('forum.forum', ['forum' => $forumCol]);
}
然而,无论我尝试上面的内容有多少种不同的变体,我都无法加载线程或用户。使用 $forum 变量添加页面时。我在论坛和相关版块中获得了一个集合,但线程正在加载为一个空集合(因此我无法加载用户)。
对于这种急切加载,我的语法不正确吗?我已经为此工作了几个小时,非常感谢任何帮助。
谢谢
编辑:
Sandeesh,我也是这么想的,但我已经尝试过了,线程仍然是一个空集合。另外,以防万一你想知道我已经检查了我所有的关系并且它们工作得很好。这是 $forum 集合的屏幕截图:
如果有人好奇我是如何解决这个问题的,请在下面回答。
预加载约束应该 return 查询生成器,而不是集合。你的错误在于 first()
和 get()
。您也不需要使用 return。
public function show($forum)
{
$forumCol = Forum::with(['boards' => function($query) {
$query->with(['threads' => function($query) {
$query->with('user')->latest()->take(1);
}]);
}])->where('id', $forum)->first();
return view('forum.forum', ['forum' => $forumCol]);
}
这花了我很长时间,但我终于找到了答案!经过大量研究,我偶然发现了一个建议采用这种方法的网站:
与你其余模特关系:
public function latestThread()
{
return $this->hasOne('ReadIt\Thread')->latest();
}
然后,我可以像下面这样简单地预加载,而不是对一个关联设置条件:
$forumCol = Forum::with(
'boards',
'boards.latestThread',
'boards.latestThread.user'
)->where('id', $forum)
->first();
当我看到这个时,起初我非常怀疑。我测试了它,但它确实有效。你可以使用hasOne,即使关系是hasMany,它也会得到第一个。现在我不确定为什么你之后能够组织以确保你获得最新的线程,但它有效!
希望对您有所帮助。