私はこのコードをLaravel 5にあります。Eloquentを使用して、完全に機能しています。
$filterTask = function($query) use ($id) {
$query->where('taskid', $id);
};
User::whereHas('submissions', $filterTask)->with(['submissions' => $filterTask])->get();
基本的には、フィルターされた提出物を持つユーザーのみを取得することを目的としています。ただし、同じコールバック関数でwhereHasとwithの両方のメソッドを実行するのは無駄です。それを簡素化する方法はありますか?
ありがとう。
パフォーマンスの点では、ここでは何も最適化できません(雄弁な関係から結合に移動する場合を除く)。 whereHas
の有無にかかわらず、2つのクエリが実行されます。 1つはすべてのユーザーを選択し、もう1つは関連モデルをロードします。 whereHas
条件を追加すると、サブクエリが追加されますが、それでも2つのクエリです。
ただし、構文的に query scope をモデル(またはこれをより頻繁に使用する場合はベースモデル)に追加することで、これを少し最適化できます。
public function scopeWithAndWhereHas($query, $relation, $constraint){
return $query->whereHas($relation, $constraint)
->with([$relation => $constraint]);
}
使用法:
User::withAndWhereHas('submissions', function($query) use ($id){
$query->where('taskid', $id);
})->get();
'マクロ可能'方法(Laravel 5.4 +)
これをサービスプロバイダーのboot()
メソッド内に追加します。
\Illuminate\Database\Eloquent\Builder\Eloquent::macro('withAndWhereHas', function($relation, $constraint){
return $this->whereHas($relation, $constraint)->with([$relation => $constraint]);
});
静的関数を使用して@lukasgeiterからの回答を拡張したいと思います。
public static function withAndWhereHas($relation, $constraint){
return (new static)->whereHas($relation, $constraint)
->with([$relation => $constraint]);
}
使い方は同じ
User::withAndWhereHas('submissions', function($query) use ($id){
$query->where('taskid', $id);
})->get();