#laravel #postgresql
Вопрос:
Я хочу удалить предложения where в некоторых условиях:
$q = Thread::with('comments')->take(10);
if(strlen($input) < 4){
$result = $q->where('title', '~', "^$input$")->get();
if($result->isNotEmpty()){
return $resu<
}
// if was empty:
}
// How to clean the where clause from the above here? because it affect the query below:
$result = $q->where('title', 'like', "%$input%")->get();
Проблема в том, что первое предложение where влияет на второе, если данные были пустыми, как я могу удалить существующие предложения where, когда это необходимо? также newQuery()
в моем случае это не работает.
Обратите внимание, что я использую два отдельных оператора в postgres ~
и ‘like’
Что-то вроде reorder() для предложений where
Ответ №1:
Да, есть способ сделать это
$q = Thread::with('comments')->take(10);
if(strlen($input) < 4){
$result = $q->where('title', '~', "^$input$")->get();
if($result->isNotEmpty()){
return $results;
}
}
// getQuery() — это метод построения запросов, который содержит все группировки, выборки, заказы, где, объединения и т. Д. Для запроса, к которому вы обращаетесь или пытаетесь создать.
$q->getQuery()->wheres= [];
$result = $q->where('title', 'like', "%$input%")->get();
Ответ №2:
Использовать условные предложения
$threads = Thread::with('comments')->when(strlen($input) < 4, function ($query) use ($input) {
return $query->where('title', '~', "^$input$");
}, function ($query) use ($input) {
return $query->where('title', 'like', "%$input%");
})->take(10)->get();
https://laravel.com/docs/8.x/queries#conditional-clauses
Если вы хотите внести в него второе изменение, я бы написал эту логику следующим образом. Комментарии загружаются только в том случае, если они необходимы.
if (strlen($input) < 4) {
$threads = Thread::where('title', '~', "^$input$")->take(10)->get();
if ($threads->isNotEmpty()) {
return $threads->load('comments');
}
}
return Thread::with('comments')->where('title', 'like', "%$input%")->take(10)->get();
Комментарии:
1. Что произойдет, если первое условие было пустым? посмотрите на мой код, он дал второй шанс, если он был пустым
2. Если вы хотите дать второй шанс, снова запустите запрос с самого начала.
3. Да, я ищу это место, как не дублировать это…
4. Я обновил свой пост.
Ответ №3:
если вы клонируете перед добавлением where, это работает так же, как удаление where
...
if(strlen($input) < 4){
$result = (clone $q)->where('title', '~', "^$input$")->get();
if($result->isNotEmpty()){
return $results;
}
}
$result = $q->where('title', 'like', "%$input%")->get();
...
Комментарии:
1. Мне нравится этот подход больше, чем другие ответы.