Image Alt

fofx Academy

  /  Laravel   /  Laravel 7: Route Model Binding Improvements

Laravel 7: Route Model Binding Improvements

Route Model Binding

If you’ve been following the releases of laravel, you should probably know that this is relatively not a new feature of laravel. However, I assume you should know the current version of laravel [7.1.1], as it continues to improve on its existing codebase to increase usability.

In this Laravel article, we’ll take a look at Key Customisation, its improvement, and Automatic Scoping in Nested Resource. Alright, let’s dive in.

Key Customisation

Laravel automatically uses the “id” field to resolve Eloquent model which is pretty fine, but sometimes you may wish to resolve Eloquent models using a column other than “id”.

In previous versions of laravel, in order to implement this, you’ll go to the model, to override laravel’s default key “id” by creating a method called “getRouteKeyName()”. This method should return the desired key to resolve the Eloquent model. Doing this the right way will override laravel’s default key binding. 

Let’s use the Post model as an example to illustrate this.

Default (Laravel < 7)

Let’s create a Post model and Controller and migration.

Setup Route to show a single post, Define the schema of the table in the migration file. But behind the scenes, I’d set up factory for my post to populate the table with 2 records.

My Show() function in the PostController looks like this.

Now, we can run migration [php artisan migrate]. Don’t forget to set the guarded property in the post model to empty.

 

My database looks like this after this initial setup.

Now let’s try to look up a single post from the database.

As you can see in the URL bar, I had to pass the “id” through. What if we had another field we want to use instead of “id”. For Instance, let us pass the “title” as the parameter.

I guessed you must have tried doing it, and you probably got a 404 error.

The way to resolve this as I said earlier is to do this in the Post Model.

You can see that I returned “title”, but feel free to return anything while you use it as the query parameter.

To prove that this is working, let’s replace “1” with “Post 1”.

And as much as it should be, It works!!!

Just before now, you would do the above setup. Laravel 7 brought about the improvement in this aspect as you could do it like this.

Laravel 7

Still using the Post entity as an example, remove the GetRouteKeyName() function from the Post model. If you did, you’re back to having error 404.

Now head to your Route file, and try this out.

Now reload your page, and yes, that’s right! it worked. This flexibility makes laravel very easy to use and customise things. Feel free to change things but make sure nothing breaks.

Automatic Scoping

When injecting a model ID to a route or controller action, you will often query to retrieve the model that corresponds to that ID. Laravel route model binding provides a convenient way to automatically inject the model instances directly into your routes. For example, instead of injecting a user’s ID, you can inject the entire User model instance that matches the given ID. Let me quickly explain what Implicit binding is.

Implicit Binding:

Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name. For example:

Since the $post variable is type-hinted as the App\Post Eloquent model and the variable name matches the {post} URI segment, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI. If a matching model instance is not found in the database, a 404 HTTP response will automatically be generated.

Now that we know that, Let’s move on.

As the documentation says, Sometimes, when implicitly binding multiple Eloquent models in a single route definition, you may wish to scope the second Eloquent model such that it must be a child of the first Eloquent model.

For example, consider this situation that retrieves a blog post by slug for a specific user:

If you tried this, it will return some posts only if the user has some posts.  i.e there would have been a relationship specified for/between the two models.

When using a custom keyed implicit binding as a nested route parameter, Laravel will automatically scope the query to retrieve the nested model by its parent using conventions to guess the relationship name on the parent. In this case, it will be assumed that the User model has a relationship named posts (the plural of the route parameter name) which can be used to retrieve the Post model.” — Laravel Docs.

What the above statement is saying is that: If you don’t use key customisation, the layer of security is gone. i.e the fact that you want posts that belong to a user to be returned.

You might ask that what if I want the default key binding which is “id” and I still want to use the “Automatic Scoping”, Well the docs didn’t explicitly state it, but you can just do this.

This will use the “id” just as the default style and you still have the “Automatic Scoping” in place.

In short, Auto Scoping only works if you use key customisation.

Bonus Tip: You can check the laravel version of a current app using this.

Are you a young developer aspiring to be fundamentally solid in laravel or an employer seeking to hire a part-time or full-time developer capable of delivering quality, scalable code? Check out our bootcamps and web development graduates here

The link below also focuses on using laravel’s core and extensive features as well as fundamental programming concepts to facilitate great interview questions in identifying a Laravel developer’s strength. This can be helpful for both employers and developers looking to secure a laravel job role.

How to Hire a Great Laravel Developer

We hope you found this article useful. Got any questions? Reach out to us.