2016-07-13 9 views
4

Недавно Laravel выпустила версию 5.3.Laravel 5.3 - Query Builder, начиная с orWhere

Есть некоторые инструкции по обновлению от 5.2 до 5.3 в следующей ссылке: https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0

Красноречивых прицелы теперь принимают во внимание ведущего булевой области видимости ограничений. Например, если вы запускаете свою область действия с ограничением orWhere, она больше не будет преобразована в нормальный режим где. Если вы полагаетесь на эту функцию (например, добавляете несколько или Where ограничений в цикле), вы должны убедиться, что первое условие является нормальным, чтобы избежать любых логических проблем.

Если ваши области действия начинаются с ограничений, никаких действий не требуется. Помните, что вы можете проверить свой запрос SQL с помощью метода toSql запроса:

Это, похоже, делает вещи немного сложнее, и обновление только добавит к нему ограничений.

У нас есть внутренний пакет, и чтобы код был простым и как можно более аккуратным, есть часть, которая полагается на запуск запроса с помощью илиWhere(), и использует это, а также концепцию закрытия внутри рекурсивного метод. Как вы знаете, рекурсивные методы лучше всего держать его коротким и простым.

Согласно ноте обновления сейчас, это наверняка не в состоянии на Laravel 5.3

мне было просто интересно, если кто-нибудь знает причину того, почему такое поведение удаляется?

Спасибо!

Update:

Я мигрировали нашу систему к Laravel 5.3. Я подтверждаю, что это затронуто только в конструкторе Eloquent, а не в Query Builder (ранее «Свободный строитель»).

Даже фиксация (которая является чертовски изменением лота) относится только к Eloquent \ Builder. https://github.com/laravel/framework/issues/14829

В любом случае, чтобы быть в безопасности, я рекомендую сделать настройку соответствующим образом. Это то, что мы сделали, хотя мы знаем, что он не нарушил наш код (на сегодняшний день).

+1

Я думаю, что для большей ясности с помощью илиWhere. Я думаю, что вы могли бы использовать первый, где это всегда верно, а затем цепочка с вашими orwheres, чтобы иметь такое же поведение. – Hammerbot

+0

Да, я понимаю, что могу это сделать. Просто он добавляет несколько дополнительных строк (хотя я знаю, что это не так много). Но мне было просто интересно, какой смысл снимать эту гибкость? Звучит неловко, чтобы отбросить поведение за рамки, которые стоят перед таким большим сообществом. Это поведение также работает в Active Records CodeIgniter. Не уверен насчет Доктрины, хотя я считаю, что это похоже на CI. –

ответ

6

Я считаю, что причина точно этот запрос тянуть: https://github.com/laravel/framework/pull/12918

Кто-то хотел бы использовать областей, как это:

User::approved()->orActive(); 

и в том случае, если orActive сфера определяется следующим образом:

public function scopeOrActive($q) { 
    return $q->orWhere('active',1) 
} 

и approved объем определяется следующим образом:

public function scopeApproved($q) { 
    return $q->where('approved',1) 
} 

В Laravel 5.2 было бы решить, чтобы:

where approved = 1 AND active = 1 

и Laravel 5.3 он решил:

where approved = 1 OR active = 1 

так что имеет смысл, однако я никогда не использовал телескопы, начиная с orWhere

+0

Спасибо Marcin! Я считаю, что вы правы, что может быть причиной перемен. Хотя это неудобно, потому что это работает для этого случая, но не для другого. Это звучит для меня, скорее, проблема с ограничениями дизайна системы, но при этом окупается конечными разработчиками. Не уверен, что кто-то нападет на меня по тому, что я только что сказал, ха-ха-ха, но это всего лишь мягкая мысль с моей стороны. –

+0

@ThomasCheng Ну, на мой взгляд, это изменение имеет смысл, однако использование этого очень ограничено. Были ли у вас области, начинающиеся с «или где»? Не могли бы вы показать какой-нибудь пример кода? –

+0

@ MarcinNabiałek. Можете ли вы ответить на такой же пост: https://stackoverflow.com/questions/45031207/laravel-5-2-orwhere-generate-and-in-query? –

0

Вот способ использовать несколько положения orWhere с булевыми. Предположим, у вас есть запрос:

выберите * от пользователя, где активен = 1 и (user_type = 1 или user_type = 2 или user_type = 3);

Но мы не всегда хотим, чтобы все запросы user_types находились в запросе, то есть мы имеем несколько логических значений, которые определяют, какие из них должны присутствовать. Это может быть достигнуто так:

$includeOne = true; 
$includeTwo = false; 
$includeThree = true; 
$query = User::where('active', 1) 
    ->where(function($q) use ($includeOne, $includeTwo, $includeThree) { 
     $q->when($includeOne, function($query) { 
      return $query->orWhere('user_type', 1); 
     }) 
     ->when($includeTwo, function($query) { 
      return $query->orWhere('user_type', 2); 
     }) 
     ->when($includeThree, function($query) { 
      return $query->orWhere('user_type', 3); 
     }); 
    })->get();