Playing
01. Bootable traits in Laravel

Episodes

0%
Your progress
  • Total: 6m
  • Played: 0m
  • Remaining: 6m
Join or sign in to track your progress

Transcript

00:00
In this snippet, we're going to look at booting inside of a trait. And by this, I mean, if we just open up this article model I have, one of my favorite ways of, for example, automatically generating a slug for a particular model, because of
00:15
course slugs are shared between different models potentially, is going ahead and using the public static boot method. So what this will do is once your model is kind of loaded up, this will go ahead and boot everything up, and you may have used this before.
00:30
And then inside of here, what we can do is register an observer. So we can say when this article is being created or when it has been created, we want to hook on a particular event. Now this is pretty straightforward.
00:43
So let's just go ahead and build this out now. Let's say static creating. So when this article model is being created, we want to run this callback. We'll get the article instance inside of here.
00:55
So this will be the actual model itself. And then what we can do is go ahead and say assign the slug, the value str slug, and that will be based on the title that we've given this. So we just pass that in.
01:06
So all that will do is it will just fill the slug column as we're creating an article. So for example, over in Roots and Web, when we want to create an article out, we don't actually have to pass the slug in, because that can get a little bit annoying having to use this outside of the model context.
01:21
So I'm going to say a new article, and what's going to happen is this will be fired when we're creating that. Before it's saved to the database and persisting, we're going to go ahead and assign the slug. So let's just come over and give that a refresh.
01:34
Come over to the database, and sure enough, that has worked. Now that's basically what I like to do. When it's something as simple as this, I like to just stick this inside of the model and forget about it.
01:44
But of course, with something like a slug, as I mentioned earlier, this could be shared between lots of different models. Let's say you had a post, a forum post, anything that could potentially have a slug, you probably want to move this functionality into a trait.
01:58
So you can just say something like, use sluggable, and then you can pop all of your functionality away in there, and you can just use this trait whenever you have something that has a slug. So let's look at just moving this over and see what happens. So inside of app, let's just do this really roughly.
02:14
Create our traits folder, and let's go ahead and create this sluggable trait inside of here. So let's create that trait out. You could, of course, call that whatever you wanted.
02:25
And let's go ahead and grab the boot method that we've just used inside of here, pop this inside of here, and go ahead and import the sluggable trait. Now of course, this isn't an article anymore, so just for the sake of naming, let's go ahead and call this model, because of course, this could be shared by different models now.
02:42
And we should see exactly the same thing. The only downside is we still have to include the fillable column in here, but I don't think that's too much trouble. So if I give that a refresh, sure enough, this works in exactly the same way.
02:53
And you might be thinking, well, we're done now. That's been moved over and we can reuse that. Well, what happens if we have a specific case where inside of our article we want to also use the boot method?
03:03
That's entirely likely. So let's go ahead and pull in this static boot method again and do parent boot. That will just go ahead and boot up the parent, of course, and we'll call the boot method on the parent, which is the model just here.
03:15
If we come over now and give that a refresh, notice if we just... Let's go ahead and move that over. Static function. There we go.
03:22
So what's happening now is this is, of course, overriding what we have inside of the trait because we have the same method. So this isn't working. And, of course, the error that we see here is just because the slug is not a nullable
03:36
column and we're not inserting that slug. Of course, this just isn't firing at all because we've overridden this. So how do we get around this? How do we do something like this inside of a trait, which could also potentially conflict
03:49
with something like this inside of our base model? Well, the key to finding this out is just diving into the base model here and looking at the boot method inside of here. And you can see that we've got a static boot trait method.
04:03
So let's come down to this. It looks quite complicated, but actually what it's doing is very, very straightforward. So these highlighted in yellow here are Laravel helpers. Class base name will just give us the base name for the class, so it won't give us app
04:17
traits sluggable. It will just give us the base name for this class using the PHP reflection API. So all this is doing is it's saying, well, grab anything that's inside of here as a trait, go ahead and get the method name that we want to call.
04:32
In this case, it will be boot sluggable. So we can actually die dump in here and die dump on that method and go ahead and give that a refresh. And you can see here we've got boot has attributes, but, of course, if we dump this out rather
04:45
than die dump, what we should see is boot sluggable. So what's happening here is it's giving us the opportunity to create a method inside of our trait, which will then go ahead and use forward static call, which is the equivalent of call user func in PHP, but using a static method.
05:04
And that will just call that method, and therefore we can go ahead and boot this up. So rather than using the main boot and overriding it, we can go ahead and call a boot method inside of here just by renaming this to boot sluggable. So now that we've done this, this will be called, and we don't need to do parent boot
05:22
in this case. So we can go ahead and get rid of that. And if we come over and give that a refresh, sure enough, that works in exactly the same way.
05:30
That works. And, of course, the boot inside of here will work as well. So for example, just to test this out, we can say static creating and go ahead and create a closure in here and say article.
05:44
And let's just override the slug. So let's say article slug equals article slug, and let's append on one just as an example. And we'll leave it at that. So let's go and give that a refresh, open this up, and sure enough, you can see that
05:58
that has also modified it. So just by making that really simple change, you can go ahead and boot stuff up inside of your traits, which can be incredibly useful. And now you know exactly how this works inside of the base model.
1 episode 6 mins

Overview

If you need to register something within the boot() method of a model, here's a quick tip to do this within a trait if needed.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!