Laravel-帮助预先加载辅助关系(我目前正在运行364个SQL查询)


Laravel - Help eager loading secondary relationships (I currently have 364 SQL queries running)

我在Laravel 4中主持了一个网站的管理端,并试图让一切都在雄辩中工作。我正在尝试构建一个具有多个关系的对象。这似乎工作正常,直到我尝试加载次要关系。

以下是我对 YourDetail 模型的调用:

$applicants = YourDetail::with(array('User', 'Application', 'SecondaryEds', 'SecondaryEds.SecondaryTypes', 'SecondaryEds.SecondaryGrades', 'FurtherEds', 'FurtherEds.FurtherTypes', 'FurtherEds.FurtherGrades', 'UniEds', 'UniEds.UniClassifications', 'UniEds.UniQualifications', 'WorkExperiences', 'WhyYou', 'StartDate', 'Referer'))->whereIn('user_id', $applicants);

我所有的关系都在各种模型中定义,并且在直接使用时工作正常。我遇到的问题是次要关系,例如

FurtherEds.FurtherTypes, FurtherEds.FurtherGrades, UniEds.UniClassifications, UniEds.UniQualifications,

等。

现在,当我运行查询时,我得到的正是我所期望的 - 大约 20 个代表各种模型的选择查询,例如,生成的引入"FurtherEds.FurtherGrades"模型的选择查询如下所示:

select * from `further_grades` where `further_grades`.`deleted_at` is null and `further_grades`.`id` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

目前为止,一切都好。。。

当我尝试通过集合对象访问这些模型时,问题就来了;

因此,假设我现在遍历我的集合,将每个对象传递给如下所示的视图:

foreach($applicants as $applicant){
    View::make('ApplicantView', compact('applicant'));
}

然后在我看来,我尝试遍历FurtherEds并回显FurtherGrades模型的一个属性:

申请人视图刀片.php

@foreach($applicant->FurtherEds as $fe)
    {{ $fe->FurtherGrades->name }}
@endforeach

现在,这将为每个申请人创建一个新的sql查询,尽管我尝试预先加载,例如

select * from `further_grades` where `further_grades`.`deleted_at` is null and `further_grades`.`id` = ? limit 1 (for each applicant)

最终结果是我的页面目前正在生成 364 个选择查询,尽管页面加载速度还不错,但似乎有点过分。

谁能解释我在这里做错了什么,并为我指出正确的方向。

对任何感兴趣的人...

我现在已经解决了这个问题:

看来我正在做的是正确加载关系,但访问它们不正确。因此,例如,如果您急于加载这样的关系:

$applicants = YourDetail::with('FurtherEds.FurtherTypes', 'FurtherEds.FurtherGrades');

然后,您应该访问如下所示的元素:

@foreach($applicants as $applicant)
@foreach($applicant->FurtherEds as $fe)
  {{ $fe->FurtherTypes->name }}
@endforeach
@endforeach

我遇到的问题是访问大写错误的较低模型:

例如。

@foreach($applicants as $applicant)
@foreach($applicant->furtherEds as $fe)
  {{ $fe->furtherTypes->name }}
@endforeach
@endforeach

Laravel足够聪明,可以识别模型中的关系,因此它知道要访问什么,但它不会将$applicant->furtherEds识别为与预先加载的模型对象相同$applicant->FurtherEds而是生成新的SQL查询。

当我在一个稍微复杂的页面上做了几次这个时,我有 2000+ sql 查询。吸取的教训...再也不会了

附言现在我已经弄清楚了如何正确使用它 雄辩正式是有史以来最好的事情,如果你遇到麻烦,绝对值得坚持。

尝试像这样加载二级相关模型:

// from the docs
You may even eager load nested relationships:
$books = Book::with('author.contacts')->get();

http://laravel.com/docs/eloquent#eager-loading