Laravel Model Lifecycle Hooks

Jun 3, 2019 · 3 min read
Image for post
Image for post
A simple example within a model ‘observable’

When writing applications, it is often necessary to weave functionality through the events that occur to an object of a class that you have created. For instance, in this example that I will briefly go through — taken from Jeffrey Way’s Laracasts TDD course — there is this concept of keeping an activity log associated to a given project.

Now, given that ‘Project’ is a class, and that any given instantiation of that class would be the ‘object’ in question, there are a few different ways of tying in functionality to the events surrounding a ‘Project’.

In the app, ‘Projects’ has ‘Tasks’ associated to them. In the picture above, there is a simple example of a ‘recordActivity’ method being called when a ‘Task’ is created or deleted. Not pictured, is a hook for when the ‘Project’ itself is created, deleted, or updated.

The reason this is significant is because this allows for dynamism in the app. For instance, lets imagine that a ‘Project’ could be updated via 3 different ways:

  1. The project’s fields could be changed
  2. The project could have tasks added or removed
  3. The project could be archived or deleted

With no lifecycle hooks, we are adding the code to ‘create an activity’ within every single function call.. well.. thats redundant. Programming is all about reusing logic and making efforts more efficient. What if the logic needed to change? Now we are in the classic situation of having to change all references everywhere. Well, the first thing you should ask is: “Why don’t we just abstract that functionality into it’s own function, and then just call it there?”. Well, yes! That’s exactly what we will do.

Really, the only difference between that solution and the solution of utilizing lifecycle hooks is that the lifecycle hooks are essentially pre-generated abstracted methods that are simply waiting to be populated with functionality, and can respond to most operations you can imagine.

A few ways to tie into Model lifecycle hooks:

  1. Listen to them in the web.php router file
Router-Access to Model Lifecycle Hooks

This is an ugly, inefficient and frankly disorganized approach towards achieving this goal… let’s see how else we can do this.

2. Accessing them from within the Model itself

Image for post
Image for post
Overriding the Model ‘boot’ method

This approach is fairly organized and can be attractive if your need to access lifecycle hooks is limited. This works by first overriding the ‘boot’ method, which gets called whenever an Object is instantiated from a Class, and then by further overriding the various hook methods from within the Model, as before. Now, if your need for plugging into a Model’s lifecycle hooks is plentiful and involves multiple abstracted sub-functions, then consider the next approach..

3. Creating an Observable Class

Image for post
Image for post
Arguably the cleanest approach to achieve this goal

This approach involves creating a new class ( using a handy artisan command “php artisan make:observable -model=ModelName” ) and then registering it within the AppServiceProvider. What this does is then give you specific access into each and every lifecycle hook ( pre-generated by Laravel ). With this, if necessary, you can then produce whatever logic necessary to complete anything you’d like to have happen.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store