Thomas Cheng Thomas Cheng - 1 month ago 26
PHP Question

Laravel 5.3 - Query Builder starting with orWhere

Recently Laravel released version 5.3.

There are some upgrade instructions from 5.2 to 5.3 in the following link:
https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0


Eloquent scopes now respect the leading boolean of scope constraints. For example, if you are starting your scope with an orWhere constraint it will no longer be converted to normal where. If you were relying on this feature (e.g. adding multiple orWhere constraints within a loop), you should verify that the first condition is a normal where to avoid any boolean logic issues.

If your scopes begin with where constraints no action is required. Remember, you can verify your query SQL using the toSql method of a query:


This seems to make things a bit harder, and the upgrade will only add limitations to it.

We have an internal package, and to keep the code simple and as neat possible, there is a part that relies on starting a query with orWhere(), and makes use of this as well as the closure concept inside a recursive method. As you know, recursive methods are best to keep it short and simple.

According to the upgrade note now, it will for sure fail on Laravel 5.3

I was just wondering if anyone knows the reason to why this behavior is being removed?

Thanks!

Update:

I've integrated our system over to Laravel 5.3. I confirm that this is only affected in Eloquent builder, and not in the Query Builder (formerly "Fluent Builder").

Even the commit (which is a hell of a lotta changes) is only on Eloquent\Builder.
https://github.com/laravel/framework/issues/14829

Anyway, to be on the safe side, I do recommend to make the tweak accordingly. That is what we did, though we know that it did not break our code (as of today).

Answer

I believe the reason is exact this pull request: https://github.com/laravel/framework/pull/12918

Someone would like to use scopes like this:

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

and in that case if orActive scope is defined like this:

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

and approved scope is defined like this:

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

In laravel 5.2 it would resolve to:

where approved = 1 AND active = 1

and in Laravel 5.3 it's resolved to:

where approved = 1 OR active = 1

so it makes sense however I've never used scopes starting with orWhere