【发布时间】:2018-06-09 00:46:33
【问题描述】:
我有一个方法需要从三个相关模型中提取信息。我有一个可行的解决方案,但我担心我仍然遇到 N+1 查询问题(也在寻找有关如何检查我是否渴望正确加载的解决方案)。
这三个模型是 Challenge、Entrant、User。
挑战模型包含:
/**
* Retrieves the Entrants object associated to the Challenge
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function entrants()
{
return $this->hasMany('App\Entrant');
}
参赛者模型包含:
/**
* Retrieves the Challenge object associated to the Entrant
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function challenge()
{
return $this->belongsTo('App\Challenge', 'challenge_id');
}
/**
* Retrieves the User object associated to the Entrant
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
并且用户模型包含:
/**
* Retrieves the Entrants object associated to the User
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function entrants()
{
return $this->hasMany('App\Entrant');
}
我尝试使用急切加载的方法如下所示:
/**
* Returns an array of currently running challenges
* with associated entrants and associated users
* @return array
*/
public function liveChallenges()
{
$currentDate = Carbon::now();
$challenges = Challenge::where('end_date', '>', $currentDate)
->with('entrants.user')
->where('start_date', '<', $currentDate)
->where('active', '1')
->get();
$challengesObject = [];
foreach ($challenges as $challenge) {
$entrants = $challenge->entrants->load('user')->sortByDesc('current_total_amount')->all();
$entrantsObject = [];
foreach ($entrants as $entrant) {
$user = $entrant->user;
$entrantsObject[] = [
'entrant' => $entrant,
'user' => $user
];
}
$challengesObject[] = [
'challenge' => $challenge,
'entrants' => $entrantsObject
];
}
return $challengesObject;
}
我觉得我遵循了文档推荐的内容:https://laravel.com/docs/5.5/eloquent-relationships#eager-loading
但不确定如何检查以确保我没有进行 N+1 次查询,而不仅仅是 2 次。欢迎对代码提出任何提示或建议,以及检查预加载是否正常工作的方法。
【问题讨论】:
-
如果您只想知道您的预加载是否有效,只需在使用
->with('entrants.user')之后转储变量$challenges并且不使用该方法。并检查结果。dd($challenges)