Installing Laravel 5.2-dev0:00
I'm recording this video on December 10th, 2015, and yeah, at the time of this recording, Laravel 5.2 hopefully isn't more than about a month off. You're never too sure, but I would imagine roughly around a month is a good bet. So let's start reviewing some of the new features, and we'll begin with implicit model binding. But first, well, how do we go and install the development version of Laravel? We can do that through Composer. Create a new project using the github laravel/laravel repo. We're going to call this Laravel 5.2, and specifically, I want the development branch. All right, so I will give that just a minute. Great.
Implicit model binding basics0:36
All right, so I will give that just a minute. Great. So let's cd in there and get set up. So what exactly is implicit model binding? Well, I'm going to show you. Now, Laravel has always, at least for quite a while now, had some implementation of route model binding, but you had to do it manually. So for example, if I were to say Route::get('user/{user}'), well, yeah, we could do something like this, receive the $user, and we automatically get that model. So if I were to return this, then you get the JSON representation of the $user, and you
like this, receive the User, and we automatically get that model. So if I were to return this, then you get the JSON representation of the User, and you don't have to do any of this stuff like app\User::findOrFail by the userID, you know, stuff like that. You don't have to do it. It just happens automatically for you behind the scenes. However, the way it always worked, if I backtrack just a ways, the way it always worked before is you would have to, within a ServiceProvider, manually bind that up. So you just say, okay, when you have this, I want to bind that to this specific Eloquent class.
Database setup and seeding1:32
So you just say, okay, when you have this, I want to bind that to this specific Eloquent class. And it's just a small step, but even from my own experiences, just so often, I wouldn't do it. But now, it's implicit. It happens automatically. So yeah, why don't we just try this out? So let's set up a quick database. I'm just going to use sqlite. And if we scroll down, we need to create the file.
I'm just going to use sqlite. And if we scroll down, we need to create the file. So touch database/database.sqlite. And as you know, we get a couple migrations out of the box. Nothing new here, but we do have a users table set up there. Okay. So next, I'm going to whip up a couple test users by doing factory(App\User::class). And why don't we create like three users? Okay. So we have Rylan, Michael, and Wellington.
Okay. So we have Rylan, Michael, and Wellington. So all I want to do now is when I request users slash and then the user ID. So in this case, if I do 3, we should get this record back. Let's try it out. php artisan serve. And if we now visit that URI in Chrome, it works. How cool is that? Easily one of my favorite things in 5.2. It just makes sense.
Inspecting router internals3:15
And now you can see that shows up. But typically, it's a non-issue. Laravel will always do something like this, so it's no problem. And if you want to take a look behind the scenes, let's go to Laravel's Router class. And why don't we just look for implicit? There you go. So let's see where this gets called. So okay, when we start substituting the bindings, we substitute implicit bindings. And if we switch down there, yeah, here we go. So notice, ultimately, our method will be findOrFail, basically.
And if we switch down there, yeah, here we go. So notice, ultimately, our method will be findOrFail, basically. But then we say route setParameter, in our case, user, equals user, create a new instance, findOrFail, and then we pass in the wildcard. So in this case, it would be three. So yeah, when we use implicit binding, Laravel behind the scenes just automatically tracks down the record for you. So yeah, we're basically saying user, findOrFail, three. And that resulting instance gets associated with the user wildcard. Now what else?
Binding multiple wildcards4:06
And that resulting instance gets associated with the user wildcard. Now what else? Well, remember, this will work for as many wildcards as you have. So for example, let's say you want to grab a User's posts or something. Well, yeah, in that case, you would do the exact same thing here. And now if post is 4, then it will do a post::findOrFail, with an argument of 4. And now you have your user instance as well as a post instance, and you didn't have to write more than one line of code. So cool. Now though, what about the situations where you're not working with a primary key?
Custom binding by username4:37
So cool. Now though, what about the situations where you're not working with a primary key? So for example, in this situation, we want to track down the User by their username, not by their ID. Okay, well, let's figure that out. Let's go back to our users table and add a username here. So we'll say table->string('username'); That does need to be unique. And then if we go back to our model factories class, let's just add that on here. So username, and I believe Faker has a username property we can use.
And then if we go back to our ModelFactory class, let's just add that on here. So username, and I believe Faker has a username property we can use. Okay, so I can now say php artisan migrate:refresh. And then if we go to php artisan tinker, once again, we'll say factory and give me three User instances. Okay, and they all have unique usernames. So let's grab this username. And if we switch to Chrome, user/2 brings up that record. But now I want to do this to track it down, but it's not working. Okay, well, in those situations, you would need a custom binding to tell the Router how
But now I want to do this to track it down, but it's not working. Okay, well, in those situations, you would need a custom binding to tell the router how to set that parameter properly. So in this case, we could go to our RouteServiceProvider, app/Providers/RouteServiceProvider.php. And now down here, we could do this, I could say Route::bind user to this closure. And now we could just say return app(User), and then say where username is equal to what you pass in, give me the first result. Okay, so now we go back to Chrome, it was failing. But if we give this a refresh, and whoops, forgot the Facade, okay, refresh.
Okay, so now we go back to Chrome, it was failing. But if we give this a refresh, and whoops, forgot the Facade, okay, refresh. And now we've said that when we use this user keyword within our routes file, well, we want to bind that wildcard to this operation here. So take note, if we were to change this to something like you, well, yeah, that's not going to work anymore. And we don't get anything. And that's specifically because this keyword is important. So in that situation, if you do want to use you, then you need to be consistent about it and update it here.
So in that situation, if you do want to use User, then you need to be consistent about it and update it here. Yeah, of course, in real life, User is appropriate. So that's what we'll do here. So yeah, that's all there is to it. Most of the time, you are just tracking things down by the primary key, in which case you can leverage this implicit binding and clean up your code that much more. But when you need to override it, and you have some special operation for how you track down a record, well, just go to your RouteServiceProvider and override it.
down a record, well, just go to your RouteServiceProvider and override it.
