У меня такой запрос:
return Expense::with('descriptions')
->when($this->string, function ($query) {
return $query->where('name', 'LIKE', '%' . $this->string . '%');
})
->orWhereHas('tags', function ($query) {
$query->where('name', 'LIKE', '%' . $this->string . '%');
})
->get();
Мне нужно как-то использовать whereHas
с when
. Если $this->string
пуст, whereHas
использовать нельзя. Поскольку он вернет все, что имеет такой Tag
, и мне нужно запускать его только тогда, когда $this->string
не пуст.
Есть ли способ написать это чисто? Я не хочу использовать if / else для проверки, установлен ли $this->string
, а затем возвращать что-то другое.
Похоже, здесь имеет смысл оператор if или какое-то условие. Почему ты не хочешь этого делать? Вы пробовали вложить orWhereHas в оператор when? В этом случае вам просто нужно быть осторожным, чтобы содержать переменные $ query в порядке.
Поскольку ваш где зависит от внешней переменной, лучший подход - построить ваш запрос с условными операторами, оценивающими ваши переменные.
Не бойтесь разбить построение вашего запроса на несколько этапов, вам не нужно все связывать и возвращать.
Более читабельно выглядит что-то вроде этого:
$builder = Expense::with('descriptions')
->where('name', 'LIKE', '%' . $this->string . '%');
if ($this->string) {
$builder = $builder->whereHas('tags', function ($query) {
$query->where('name', 'LIKE', '%' . $this->string . '%');
});
}
return $builder->get();
Принял этот ответ, так как он действительно выглядит более чистым. Однако в моем случае пришлось перейти на $builder = $builder->orWhereHas
.
Вы хотите что-то подобное?
return Expense::with('descriptions')
->when(!empty($this->string), function ($query) {
return $query->WhereHas('tags', function ($query) {
$query->where('name', 'LIKE', '%' . $this->string . '%');
})
})
->get();
Разве нельзя просто переместить
orWhereHas()
в крышкуwhen()
?