我的Laravel网站上有Jobs and Projects,它们之间有关系。我正在尝试减少查询的数量(并注意N + 1问题)。当我输出JobItems时,我渴望在控制器中加载它。
嵌套时如何执行:JobItems> Project> JobItems。
在一种情况下会发生这种情况,并且我得到重复的查询。我不确定如何渴望加载。我将概述情况:
每个JobItem都有一个小时列。
在我的项目中,我对所有关联的JobItem小时进行求和以确定项目中的总时数。 (例如,每个有4个小时的3个JobItem,然后在我的项目模型中有一个访问器,显示为projectHours = 12)。
我想列出所有JobItems和每个JobItem以具有相关Project的子元素。
所以我打电话:
在第3步中,我收到N + 1个问题和多个重复的查询。我想通过急切的加载减少这种情况,但不确定如何(在步骤1中)已经调用JobItem模型。
在我的控制器中,我有:
public function getJobItems()
{
$userId = auth()->user()->id;
return JobItem::whereHas('project', function ($query) use ($userId) {
$query->where('user_id', '=', $userId);
})->with(['project', 'user'])
->get();
}
在我的Project模型中,我有:
class Project extends Model
{
protected $appends = ['projectHours'];
public function jobs()
{
return $this->hasMany('App\JobItem', 'project_id', 'id');
}
public function getProjectHoursAttribute()
{
return $this->jobs->sum('hours');
}
}
和往常一样,如果我处理不正确,请告诉我。非常感谢。
NB。这与有关通过急切加载减少查询的SO凭单有关:How to use eager loading on Laravel model with SUM of a relationship - currently getting multiple queries (N+1)
答案 0 :(得分:1)
我将分两部分来回答这个问题:
1)预加载关系
因此,如果您尝试列出jobItem
集合,但要显示每个项目的关联Project
的{{1}}的属性,则可以像这样预先加载所需的关系:
Job
JobItem::with(['project.jobs'])->get();
运算符可用于访问嵌套关系。 (它是与加载任何关系相同的规则,因为它是各个模型上的关系的名称)
2)访问关系
我注意到,即使您有.
模型可用,您也要通过用户ID约束查询。假设您在User
模型上具有jobItems
关系,则可以改为:
User