Laravel: Booting and Initializing Models with traits
Betcha’ you didn’t know you can do two things
One of the advantages of Eloquent ORM is how it plays nice with traits. When you use an Eloquent Model, you can execute logic when you start using the model itself.
The booting method is very magical since you can attach a Trait to the model, and if you put some methods on the trait, these will be called when you start using the Model. These follow the pattern boot{Trait}
and initialize{Trait}
, allowing you to reuse the same code in multiple models.
Booting and Initializing
The difference between both is very simple: the boot works statically, while the initialization works dynamically. The boot will affect all instances of the Model, while the initializing will work only for its instance.
To better exemplify how these works, let’s make a trait called HasToken
. This trait has two tasks over the given Eloquent Model.
- Add an event when creating a model to log who inserted the record.
- Add a random string as a token to the model.
The first task is just a way to know the authenticated user created a new model. The second will allow our model to automatically have a random token to avoid creating it manually in each part of our application.
We can do that using a single trait:
Booting
The booting method will work over the static model. For example, if you add this trait to the Authentication
model, everything you do using this method will affect that model in particular, statically.
The method name must follow the
boot{TraitName}
pattern.
This is very handy to add callbacks to eloquent events, like creating
or retrieving
for a given Model, as these work over statically.
/**
* Boot the trait
*
* @return void
*/
protected function bootHasToken()
{
static::created(function ($model) {
// Log who created this model
Log::info('Token for ' .
class_basename($model) .
' created by ' .
Auth::user()->getKey()
);
});
}
This is very well thought: booting a model won’t be done twice, only when needed. You don’t have to be afraid of calling the bootHasToken()
method multiple times, the Eloquent ORM Model class will keep track of the booted models.
Initializing
Okay, we can do static-level things using the boot method, but to manipulate the model instance itself, we need to use the initializing method. You can create an initializer by using the initialize{Trait}
pattern.
/**
* Initialize the trait
*
* @return void
*/
protected function initializeHasToken()
{
// Automatically create a random token
$this->token = Str::random(100);
}
The initializing will run each time a new Model is instanced.
And that’s the magic. Happy coding.