Extracting some functionality to a trait but need to use the static booted method within that trait? Here's how.
Let's say we're registering an Eloquent event listener on our model to generate a username for a user when they register. While there might be better ways to handle this globally, we'll stick with this example.
class User
{
public static function booted()
{
static::creating(function (User $user) {
// some code to generate a username
});
}
}
Imagine another model in your application that also needs the same functionality. Extract to a trait, right?
trait GeneratesUsernames
{
public static function booted()
{
static::creating(function (User $user) {
// some code to generate a username
});
}
}
Sure, but if we create a trait like this and apply it to two models, this will override the booted
method, meaning that our trait effectively controls what happens inside booted
.
We want to be able to 'merge' these together.
In reality, that's not what happens, but instead, we want both the booted
method inside the trait to be invoked and the one in the Eloquent model we're using.
Instead, we'll specifically target the booted method with our trait name. Here's the complete code.
trait GeneratesUsernames
{
public static function bootedGeneratesUsernames()
{
static::creating(function (User $user) {
// some code to generate a username
});
}
}
class User
{
use GeneratesUsernames;
public static function booted()
{
// this still works!
}
}
Notice the bootedGeneratesUsernames
name of the method inside that trait. Laravel will now call both the booted
method on the model and the bootedGeneratesUsernames
method on the trait.
Basically, whatever the trait is named, append the name to the end of the booted
method inside that trait.
Now, you're able to apply this trait to multiple models, even if they already contain a booted
method, and everything will work as expected!