当嵌套3深时,在laravel查询上急切加载

时间:2020-02-22 17:21:43

标签: laravel eloquent

我的Laravel网站上有Jobs and Projects,它们之间有关系。我正在尝试减少查询的数量(并注意N + 1问题)。当我输出JobItems时,我渴望在控制器中加载它。

嵌套时如何执行:JobItems> Project> JobItems。

在一种情况下会发生这种情况,并且我得到重复的查询。我不确定如何渴望加载。我将概述情况:

每个JobItem都有一个小时列。

在我的项目中,我对所有关联的JobItem小时进行求和以确定项目中的总时数。 (例如,每个有4个小时的3个JobItem,然后在我的项目模型中有一个访问器,显示为projectHours = 12)。

  • 工作
    • 项目
      • project_hours(相关作业的总和)

我想列出所有JobItems和每个JobItem以具有相关Project的子元素。

所以我打电话:

  1. JobItem模型
  2. 项目模型(作为孩子放入JobItem中)
  3. JobItem模型(用于计算项目模型中的总工时)

在第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)

1 个答案:

答案 0 :(得分:1)

我将分两部分来回答这个问题:


1)预加载关系

因此,如果您尝试列出jobItem集合,但要显示每个项目的关联Project的{​​{1}}的属性,则可以像这样预先加载所需的关系:

Job

JobItem::with(['project.jobs'])->get(); 运算符可用于访问嵌套关系。 (它是与加载任何关系相同的规则,因为它是各个模型上的关系的名称)


2)访问关系

我注意到,即使您有.模型可用,您也要通过用户ID约束查询。假设您在User模型上具有jobItems关系,则可以改为:

User
相关问题