Laravel оборачивает любой существующий запрос с условием или

У меня есть существующая модель laravel со многими условиями, привязанными к ней. т.е. ГДЕ username='john' И (updated_at > "2017-01-01" ИЛИ... ) И...

Я не знаю, сколько было предыдущих запросов, и у меня нет к ним доступа. У меня есть доступ к экземпляру модели только после того, как он получил некоторые условия.

то есть у меня есть функция, которая получает модель в качестве параметра, и я хочу добавить условие ИЛИ к уже существующему wheres

function notDeleted($model) {
  //  model has already a bunch of where/or where conditions at this point
  //  i want return rows, that match either all the previous conditions
  //  OR this new condition that i add inside this function.
}

Я хотел бы добавить условие ИЛИ следующим образом.

Select * from users WHERE ( (query1 AND query2 AND ...) OR deleted_at IS NULL);

если вы просто используете ->orWhere, то запрос будет

select * from users where query1 AND query2 AND ... OR deleted_at is null

Примечание: имена таблиц, столбцов и т. д. созданы для сообщения SO, мой реальный вариант использования немного сложнее.


person Rainer Plumer    schedule 03.08.2017    source источник


Ответы (3)


У меня была аналогичная проблема, и вот как я ее решил:

// Create new \Illuminate\Database\Query\Builder with current wheres in a group
$new_query = $query_builder->getQuery()->forNestedWhere();
$new_query->addNestedWhereQuery($query_builder->getQuery());

// Add the new query in another group
$new_query->whereIn($fk_field,                                   
        function($q) use ($index_name, $args) {
            // Ignore the Sphinx stuff, just add your new condition here.
            $q->select(\DB::raw(SphinxSearch::getRawSelect($index_name)))
                ->where('query', SphinxSearch::getRawQueryString($args));
});

// Replace original \Illuminate\Database\Eloquent\Builder's internal              
// \Illuminate\Database\Query\Builder with the new one                   
$query_builder->setQuery($new_query);
person Sebastián Grignoli    schedule 11.11.2020

Поместите критерии, которые вы хотите обернуть в закрытие:

$model->where(function($query) {
        $query->where('field', 'value')
              ->where('field2', 'value');
    })
    ->orWhereNull('deleted_at');
person Jed    schedule 03.08.2017
comment
Загвоздка в том, что критерии, которые я хочу обернуть, уже добавлены в модель. Я ищу способ обернуть уже существующие/примененные условия. если посмотреть мой пост, то в нем есть функция notDeleted. Я хотел бы добавить одно условие orWhere к любым условиям, которые уже есть в модели параметров. - person Rainer Plumer; 03.08.2017
comment
Сначала вам нужно будет обернуть предыдущие условия в замыкание. Если у вас нет доступа к ним, вам может потребоваться создать другой запрос с вашими критериями «ИЛИ» и объединить их в союз. laravel.com/docs/5.4/queries#unions - person Jed; 03.08.2017

Попробуйте обернуть условие, подобное приведенному ниже.

SomeModel::where(function($q){
    $q->where(query1 AND query2 AND ...)
      ->orWhere(deleted_at IS NULL);
})->get();

Вышеприведенный код является просто образцом. Вам нужно изменить в соответствии с вашими требованиями.

Для получения дополнительной информации перейдите по этой ссылке Группировка вложенных параметров

person laktherock    schedule 03.08.2017
comment
разместил комментарий выше, который относится и к этому сообщению - person Rainer Plumer; 03.08.2017