I was recently tasked with updating a project from laravel 5.2 to 5.3. I know even 5.3 is an old version now, but the project has fallen behind on laravel versions for some reason. The update was rather simple, and most of what I had to do was make sure that request validations were properly defined given how laravel 5.3 changed the way validations are handled. However, a couple of days ago I received a notification that something wasn’t right on the platform, and it was returning the wrong results for certain filtered assets.
Since the recent work that had been done in the files that were involved in the broken feature had nothing to do with the problem, the first suspect was the laravel update. After much digging I found out that a rather complex database query had an ‘AND’ in laravel 5.2, but an ‘OR’, when using laravel 5.3. For some reason that I still ignore a model scope was being initialized with
orWhereHas. Laravel 5.3 changed how Eloquent handles those cases, and it “now respect[s] the leading boolean of scope constraints” according to the upgrade guide.
In laravel 5.2 the leading boolean wasn’t respected, and scope constrainst were always constructed using
AND. This was problematic in most cases where people wanted to start their scopes with
OR. However, in this case,
AND was the correct way to construct the query. The fact that the program worked before the update was mere coincidence. An unintentional use of a ‘feature’ in laravel 5.2 that was changed (should I say a bug that was fixed?) in laravel 5.3.
Given the fact that I ignore why the original developer felt it was necessary to use
orWhereHas in the (rather complex) scope, I decided to pass the issue along the chain to the original developer in hopes he would have a better ideas of whether changing the
orWhereHas for a simple
whereHas would have other implications.
You can read the upgrade guide, or this stack overflow question about leading booleans in eloquen scope constraints, or the original pull request for the change in laravel’s eloquent to learn more about the change that laravel 5.3 introduced in regards to how it constructs queries when eloquen scopes are used.