I’m working on a Laravel application that basically lets users make collections of eBay products. For those collection I use a model called
ProductList. I initially wanted to call that model simply
List, but that is a php reserved word.
Because I wasn’t happy with how wordy Product List sounds, I decided to name my route simply
lists. I can view all lists going to
GET /lists, or
POST to that same url to make a new list, but when I tried to got to
GET /lists/1 to view the first list, I would not get what I expected. Instead of a populated
ProductList model in my controller, I was getting an empty model. The first symptom I saw was that trying to output the list name in my blade template resulted in nothing being printed out.
This got me scratching my head for a little bit. The controller’s method was well declared, so I referred to the documentation to see what might be going wrong. None of my previous experiences working with Laravel had had this kind of issue, but looking at the docs is always a good start.
The documentation states “Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name”. The important part here is “whose type-hinted variable name match a route segment”. The
show method of the controller created using artisan had a variable type-hinted as
$productList. Now I just had to check if the route segment matched that name. For doing that, since my routes file uses the resource method to declare the
lists route which means I can’t see the route in the routes file, all I had to do was
php artisan route:list on the command line, and the list of all routes was printed out. Sure enough the route segment, and the type-hinted variable didn’t have a matching name. All I had to do now was edit the
show method’s signature so that the type-hinted variable had a matching name with the route segment. After doing that, everything worked just fine.
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.
I recently installed Laravel in a Mac OS system, and when trying to migrate the database I got the following error:
” Illuminate\Database\QueryException : SQLSTATE[HY000]  The server requested authentication method unknown to the client “
After a little research, I learned that MySQL 8 uses a new authentication plugin called caching_sha_2_password for hashing user passwords. The fix is rather easy, as stated in this S.O. question: https://stackoverflow.com/questions/50026939/php-mysqli-connect-authentication-method-unknown-to-the-client-caching-sha2-pa#50776838. all you have to do is run this command:
ALTER USER 'mysqlUsername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mysqlUsernamePassword';
I found, however, that when I first ran the line above the user could not be altered:
ERROR 1396 (HY000): Operation ALTER USER failed for 'specs_manager_user'@'localhost';
At the moment I was using the database that the user has privileges on, so I switched to the mysql DB
And ran the
ALTER command again, and this time it worked.
Something worth noting is that the first time I searched for the issue I got to this S.O. question https://stackoverflow.com/questions/22362779/the-server-requested-authentication-method-unknown-to-the-client which is basically the same problem, but the other way around. In that question, they say that mysql is using an outdated auth plugin. It wasn’t until I looked at the laravel logs, and found the full error message stating that:
” The server requested authentication method unknown to the client [caching_sha2_password] at “
that I could find the right solution to this issue.