DRYing up code with Eloquent Model Observers

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so I've recently been working on a few projects where I have to generate data when I actually store something within laravel again and again and again and this is data that comes from data I'm already saving now that probably doesn't make sense I'm going to give you a rough example and then we're going to look at how we can solve this in a few different ways so let's say for example somewhere in a controller and I'm just going to do this within the roots for now I was creating a forum topic well obviously when we are saving something out the envira fell either using this or using the create method directly on a module name we would say something like title and then we would assign this to whatever it's been provided when we go ahead and create this and then alongside a topic we might also have something like a slug now you may know that you can use the STR slug helper within laravel to pass through exactly the same thing that you're trying to store and then in this case since we have nude up a topic model on its own we would go ahead and call save so either way that you do this whether you use topic create and then pass an array through you would have to every time you create the topic go ahead and pass this in manually calling STR slug so sometimes these things get a little bit annoying this is a really simple example but you may have other circumstances where you are wanting to save something from data so that you already have and that's why I meant by the explanation of the star this video so what we're going to be doing in this part we're just going to set up really basic functionality to store a topic we're going to look at the problem once again and then we're going to look at a few solutions to get around this so the first thing I want to do is just come over to the projects I'm working and I'm going to go ahead and make a migration here or in fact what I could do is make a model so create a topic model and also generate a migration alongside that so let's just come over to this create topics table migration go ahead and store what we need and we're going to keep this really really simple just for the sake of this so I'm going to go ahead and create a string here I'm not going to relate this back to a user because we're just kind of this is an example so let's go ahead and migrate this I'm going to come over to EMV and just switch this over I'm currently using Postgres so I'm just going to switch over the port as well here - and also the database name as well okay so if we go and run our migrations so PHP artisan migrate let's go over to the database just check this out and you can see that we have our table in there and of course because we generated that model we also have this just hit - so over in routes and we're let's actually go ahead and store this and then we'll move on to look at a couple of solutions so once again you can either use topic model on its own and use the static create method or what I like to do is go ahead and create a new topic explicitly and then start to set properties on this so let's say the title was just again hello there and again this would come from your request data so if you're working within a controller you would have your request object in here and you would obviously pass this directly into here but just for now we'll go ahead and hard-code it and we would go ahead and like we've already seen use STR slug to pass in whatever a user has provided and then we go ahead and we just save that out so if we just prefix this with app just so we don't break anything come over to the browser give that a refresh and over in the database we see this here so regardless of what you're doing this could become not a problem but it's a lot more convenient when you have data like this that you need to hook into eloquent model events you may wish to do this you know kind of get rid of this step all together just to make your life a lot easier and of course there are countless reasons why you might want to do that and once we've finished the short series we'll see that we can hook in any kind of event that we want whether it's assigning data firing a separate event within laravel sending an email whatever you want to do we're going to cover it so let's jump over to the next part and take a look at the first solution of doing this which will help you out later on so the first solution that we're going to look at it's not necessarily the best solution but it does have its place depending on what you want to do so what I'm going to do is hop over to the topic model and we're going to create a mutator and by this I mean that with in our model we can define out that when we get which is an accessor or set we can use an access or mutator so in this case we would say well when we're setting the title attribute on this model we're going to get through a value because we know that that where we're going ahead and setting it so if I just do a diagram point value here we know that over here we are setting this here now if I come over and refresh you can see that we actually get our value dumped out so this is basically something you could use to hook in the creation of a slug alongside a title now the only problem here is that the way that we set things is we say this attributes we go ahead and define the actual attribute in this case it's title and then we set it to that value and this is useful if you wanted to maybe make the title all lowercase if you wanted to change this title in some way and of course this will work with any attributes for your setting now the only problem here is that we can set the slug in here but we also have to set the title as well so we could do something like this we could say STR slug value so we're taking the title slug refining it and setting it to slug and therefore when we save this model the attribute will be set and that will be stored in the database so if we just get rid of this slug here or at least comment it out so we can go ahead and have a look we know that this is stored in the database here let's get rid of this one first of all and come over and see what we get now so you can see that this will have done exactly that now the reason this is not the best solution is that we actually have to do this as well and you can imagine that your model if you are doing this multiple times for different attributes would literally get filled up and that's not always great it looks a little bit messy and really this kind of thing is meant for doing this it's more meant for just the attribute you're setting so that's one solution and this does have its place like I said if you wanted to do anything with the value that you're currently setting you could do this and what I will also do is probably extract this out to a trait and use it within your topic model rather than go ahead and define them all here I would create a trait for this personally just to keep things nice and tidy either way that is the sim this way that we could do this but not the most clean in the next part we're going to take a look how we can set up a simple observer to actually do this okay so we've established that this probably isn't the best solution so I'm going to go ahead and get rid of this from the model we're not going to touch the model at all in this case what we're going to do is rather than do this here once again we're going to set up an observer for an action on a model or at least an event on a model so if you weren't aware that when you go ahead and new up say a topic or use the create method eloquent will actually find events that we can listen to so just as a really quick example if we go over to providers and say app service provider under the boot method we could actually pull in this model and we can go ahead and observe a particular event on this model so we have things like creating which is while the models being creating we have created once it's been created we have things like saved or saving if you were kind of saving something out updating updated all of that kind of stuff now in our case when we're creating a topic maybe we want to do something to this topic and we know that we do want to do that we want to go and we want to add a slug in so in this case what we have is a callback and in the next part we're going to look at setting up a class for these kind of observers to tidy things up if you want to do lots of different things rather than banging them all inside of this provider now into here we get a topic so from here if we just do a die dump on this topic we know that when we go and create this we should see at this in here so let's go ahead and refresh and you can see here we do in fact get that topic and that means that what we can do is we can kind of intervene in the creation of this topic so all that means is taking the topic that we receive in here and doing something with the property much better solution we've not had to update our model we're just creating a separate listener for this event so now we need to do is go ahead and say STR slug because we have that topic in there we can still grab the title and that is pretty much it we're done so while this is being created this will happen and then when we go and save it we will have that property in there get rid of that line there go over to our page give this refresh refresh the database and you can see it's worked in exactly the same way now this is a well and good but sometimes if you are you know having a lot of events here if you have lots of models you are listening to things on you can imagine this is going to get pretty crazy so we're going to quickly look at how we would create a set provider for this which would at least be the first step in keeping this a little bit tidier rather than putting everything in our app service provider because it's highly likely that you'll have other things inside of here as well so what we would do is if you're not familiar with providers and making them you would come over here to the command line and use artisan to make a provider and I would call this something like eloquent event service provider and of course you can choose any name you want and if things did get super crazy you could create a separate one for each model I wouldn't really recommend doing that but we'll take a look in the next part how we create that class it would be a little bit cleaner anyway so now that we have this we need to obviously register this over in config app alongside all of our other providers so that's all the way down and just under here let's go ahead and pull this in so I'm going to duplicate this down and give the name of that new service provider so now we have a kind of separate space to do what we've done over here so I can take this and leave this kind of alone and go ahead and place it in here instead and that means that at least we've separated it away from everything else now still though we're going to end up in the situation where we have lots of different events for lots of different models so how do we solve that well we're going to cover that in the next part and do pretty much exactly the same here but with a little bit more flexibility and make this a little bit tidier now I've established that this solution is a lot better but still we already know that we're going to run into problems later we need lots of events for lots of models so we solve this with model observers and we're going to take a look behind the scenes in laravel as well to look at kind of how this works so when we generate an observer we can actually do this on the command line laravel doesn't have a command to generate a model observer so we have to kind of do this manually but it's not too much Travel because really all it is is substituting this call back for a particular class so in the app directory what I would typically do and I think this is out in the manual as well is create an observers folder now inside of here I would create an individual observer for each type of model now in this case we have a topic so we would create a topic observer but in the case of anything else I post a user you can do it exactly the same thing so we won't be covering that but once you know how to do this you know how to do it for any model you need so let's set up the namespace so it's now on the app and observers and let's go ahead and fill this in so topic of server and we're done so now to actually register this observer before we create any methods on here how do we do this well let's go ahead and get rid of this instead what we do is we use observe so what we're now doing is we are replacing this with the full class path so in this case you can either import this at the top or say something like app observers and then say topic observer now if you were going ahead and doing this for a user you may do this following so user and the user observer maybe you have a post you would do exactly the same thing you kind of get the idea the only difference now though is that however many we register of these in here it really doesn't matter too much because we're not adding all of our logic in here as well as our individual observers so this makes things a little bit cleaner it's unlikely that you're going to have hundreds of models so really this keeps things nice and tidy so we're at the point where we have an eloquent event service provider completely separate provider and now we're linking this to a class so what do we do over in this class well we just do the same thing but we define these out as methods it's as simple as that we're just replacing the method call that we did earlier with a class with individual methods so in our case we would say creating we again receive a topic into this and we can type in this as well for a little bit of strict checking so let's go ahead and use app topic and then in here we just do exactly what we want to do but now we can do anything in here and it doesn't really matter because we're in a separate class so in this case all I would want to do is say topic and set the slug and just before we do this let's go ahead and dine dump on the topic just so we can see that this does actually work so we've set this up all looks good and we can come over and check this out give that a refresh and we get that topic again now if we come over to the model that we extend when we create any models this is again part of the laravel framework and we check out this observe method let's take a look at this you can see here that we obviously pass in that class that we've just defined and then in this case we are checking if the event that we're listening on so in here we are using get observable events so let's just take a look at this so these are all of the observable events within laravel so we can use any of these if we need to so back to the observe method in the same class iterating through each of them observable events if that particular method exists on the observer that we've created so for example if a topic is being restored maybe so we would have a restored method if it is being restored but the method doesn't exist there's no point registering an observer for it and we register the event just here so again this is in the same class so we can just come over to this and all this is doing is at listening for eloquent dot the name of the event and then going ahead and running what we've defined inside of these methods so have a really good look through this if you are interested in kind of diving into the scenes behind the scenes of any of these classes within zoravar it's always a good idea to do either way we kind of know how this works now if saya topic is being created and the observe that we've registered exists or the method on the observer we've registered exists then we know we're going to run it so in this case then let's go ahead and say topic slug set this to STR slug passing in the topic title it just works in exactly the same way and we are done so now come over here give that a refresh and I ruin the database we get what we need so I we finally ended up at this kind of solution and this is the best solution because it allow us to write as much logic or code in here that we need to go ahead and separate it out from either our app service provider or in fact this provider here so I think for smaller applications there's nothing wrong with doing topic creating in here and passing in a closure I wouldn't say don't do that but if things start to get a little bit crazy break these out into observers or if you're kind of looking ahead to the future go ahead and create an observer now just keep things easy to update later on either way that is just a really simple idea of setting a slug for a topic every time we create it but of course now you're free to do anything you like and of course if you need to remind yourselves of what is being observed so what's being listened to all the different events then of course you can come over to here follow it down and we know that we have this get observable events methods so we can go in just open this and check these out just here
Info
Channel: Codecourse
Views: 13,337
Rating: undefined out of 5
Keywords: learn to code, tutorials, codecourse, php, web development, learn php, php tutorials, code, laravel, framework, laravel 5, model observers, mutators, drying, drying code, eloquent, models
Id: 0_Y5IPkimEE
Channel Id: undefined
Length: 16min 29sec (989 seconds)
Published: Tue Feb 07 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.