У меня есть этот код в Laravel 5, используя Eloquent, который отлично работает:
$filterTask = function($query) use ($id) { $query->where('taskid', $id); }; User::whereHas('submissions', $filterTask)->with(['submissions' => $filterTask])->get();
В основном цель состоит в том, чтобы получить только тех пользователей, у которых есть отфильтрованные материалы, в которых есть любой из них. Однако, кажется, тратить время на запуск как whereHas, так и с помощью методов с той же функцией обратного вызова. Есть ли способ упростить его?
Благодарю.
Что касается производительности, вы ничего не можете оптимизировать здесь (кроме случаев, когда вам нужно перейти от красноречивых отношений к объединениям). С или без whereHas
будут запущены два запроса. Один, чтобы выбрать всех пользователей другой, чтобы загрузить связанные модели. Когда вы добавляете условие whereHas
добавляется подзапрос, но все равно два запроса.
Однако синтаксически вы можете немного оптимизировать это, добавив область запроса к своей модели (или даже базовую модель, если вы хотите использовать это чаще):
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();
Вы можете использовать его:
User::whereHas('submissions', $filterTask)->get();
Вам не нужно использовать метод ->with()
. В приведенном выше коде будут отображаться все пользователи, у которых есть представления, равные вашим правилам.