Overview
Laravel’s Eloquent provides several model events that allow you to hook into the lifecycle of a model. These events can be used to execute custom logic when specific actions occur.
Here is a list of the available model events in Laravel:
Lifecycle Events
-
retrieved
-
Triggered after a model is retrieved from the database.
-
Example:
Model::retrieved(function ($model) { // Logic here });
-
-
creating
-
Triggered before a model is created and inserted into the database.
-
Example:
Model::creating(function ($model) { // Logic here });
-
-
created
-
Triggered after a model has been created and inserted into the database.
-
Example:
Model::created(function ($model) { // Logic here });
-
-
updating
-
Triggered before an existing model is updated in the database.
-
Example:
Model::updating(function ($model) { // Logic here });
-
-
updated
-
Triggered after an existing model has been updated in the database.
-
Example:
Model::updated(function ($model) { // Logic here });
-
-
saving
-
Triggered before a model is saved (either created or updated).
-
Example:
Model::saving(function ($model) { // Logic here });
-
-
saved
-
Triggered after a model has been saved (either created or updated).
-
Example:
Model::saved(function ($model) { // Logic here });
-
-
deleting
-
Triggered before a model is deleted or soft-deleted.
-
Example:
Model::deleting(function ($model) { // Logic here });
-
-
deleted
-
Triggered after a model has been deleted or soft-deleted.
-
Example:
Model::deleted(function ($model) { // Logic here });
-
-
restoring
-
Triggered before a soft-deleted model is restored.
-
Example:
Model::restoring(function ($model) { // Logic here });
-
-
restored
-
Triggered after a soft-deleted model has been restored.
-
Example:
Model::restored(function ($model) { // Logic here });
-
Order of Events
When saving a model (either creating or updating), the events are triggered in the following order:
saving
creating
orupdating
(depending on the action)created
orupdated
(depending on the action)saved
For deletions:
deleting
deleted
For soft-deletion restoration:
restoring
restored
How to Use Model Events
You can register these events:
1. The Model Class Itself
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class YourModel extends Model {
protected static function booted()
{
static::creating(function ($model) {
// Logic here
});
static::deleted(function ($model) {
// Logic here
});
}
}
2. AppServiceProvider (Globally for All Models):
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Models\YourModel; // Replace with your actual model
use Illuminate\Support\Facades\Log;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
* @return void
* */
public function boot()
{
// Listen for the "deleting" event
YourModel::deleting(function ($model) {
Log::info('Model is about to be deleted:', $model->toArray());
});
// Listen for the "deleted" event
YourModel::deleted(function ($model) {
Log::info('Model has been deleted:', $model->toArray());
});
}
/**
* Register any application services.
* @return void
*/
public function register()
{
//
}
}
Replace YourModel
with the model you want to listen to. You can also add your own logic instead of logging, such as sending notifications, auditing, or performing cleanup tasks.
3. Event for Multiple Models
If you need to handle deleted events for multiple models, you can repeat the process for each model or use a generic approach by creating a trait.
Trait Example
Create a trait to register the event:
namespace App\Traits;
trait RegistersModelEvents {
public static function bootRegistersModelEvents()
{
static::deleting(function ($model) {
\Log::info('Model is being deleted:', $model->toArray());
});
static::deleted(function ($model) {
\Log::info('Model was deleted:', $model->toArray());
});
}
}
Then use the trait in any model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Traits\RegistersModelEvents;
class YourModel extends Model {
use RegistersModelEvents;
}
This approach keeps your AppServiceProvider
clean and reusable for multiple models.
Listen events on all Eloquent models globally
You can use Illuminate\Database\Eloquent\Model
in your AppServiceProvider
to globally listen for events on all Eloquent models. However, it requires careful implementation because it will impact all models in your application, including Laravel’s built-in models like those for authentication.
Here’s how you can set it up:
1. Use Model’s Global Events
You can attach listeners to Model
directly in the AppServiceProvider
.
For example:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* @return void
*
*/
public function boot()
{
// Listen for the "deleting" event on all models
Model::deleting(function ($model) {
Log::info('A model is about to be deleted:', [
'model' => get_class($model),
'attributes' => $model->toArray(),
]);
});
// Listen for the "deleted" event on all models
Model::deleted(function ($model) {
Log::info('A model has been deleted:', [
'model' => get_class($model),
'attributes' => $model->toArray(),
]);
});
}
/**
* Register any application services.
* @return void
*/
public function register()
{
//
}
}
2. Be Cautious
While this approach is convenient, it applies to all models, including those you might not want to track, like PasswordResets
or Sessions
. To mitigate this:
-
Filter by Model Type: Add conditional checks to ensure you act only on specific models.
Model::deleted(function ($model) { if ($model instanceof \App\Models\YourModel) { // Perform your specific logic } });
-
Exclude Specific Models: Maintain a list of models to exclude.
Model::deleted(function ($model) { $excludedModels = [ \App\Models\ExcludedModel::class, \Another\Namespace\Model::class, ]; if (!in_array(get_class($model), $excludedModels)) { Log::info('Model has been deleted:', [ 'model' => get_class($model), 'attributes' => $model->toArray(), ]); } });
3. Alternative: Using Traits
If the global approach seems too broad, you can implement a custom trait to add event handling for specific models. For instance:
Trait Example
namespace App\Traits;
trait HandlesModelDeletion {
public static function bootHandlesModelDeletion()
{
static::deleting(function ($model) {
\Log::info('Model is being deleted:', $model->toArray());
});
static::deleted(function ($model) {
\Log::info('Model has been deleted:', $model->toArray());
});
}
}
Usage in Models
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Traits\HandlesModelDeletion;
class YourModel extends Model {
use HandlesModelDeletion;
}
Conclusion
Using Model
in the AppServiceProvider
is a powerful way to globally manage events, but it should be used with caution to avoid unintended side effects. If you only need this behavior for specific models, traits are a cleaner and more targeted approach.