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

  1. retrieved

    • Triggered after a model is retrieved from the database.

    • Example:

      Model::retrieved(function ($model) {
          // Logic here 
      });
      
  2. creating

    • Triggered before a model is created and inserted into the database.

    • Example:

      Model::creating(function ($model) {
          // Logic here 
      });
      
  3. created

    • Triggered after a model has been created and inserted into the database.

    • Example:

      Model::created(function ($model) {
          // Logic here 
      });
      
  4. updating

    • Triggered before an existing model is updated in the database.

    • Example:

      Model::updating(function ($model) {
          // Logic here 
      });
      
  5. updated

    • Triggered after an existing model has been updated in the database.

    • Example:

      Model::updated(function ($model) {
          // Logic here 
      });
      
  6. saving

    • Triggered before a model is saved (either created or updated).

    • Example:

      Model::saving(function ($model) {
          // Logic here 
      });
      
  7. saved

    • Triggered after a model has been saved (either created or updated).

    • Example:

      Model::saved(function ($model) {
          // Logic here 
      });
      
  8. deleting

    • Triggered before a model is deleted or soft-deleted.

    • Example:

      Model::deleting(function ($model) {
          // Logic here 
      });
      
  9. deleted

    • Triggered after a model has been deleted or soft-deleted.

    • Example:

      Model::deleted(function ($model) {
          // Logic here 
      });
      
  10. restoring

    • Triggered before a soft-deleted model is restored.

    • Example:

      Model::restoring(function ($model) {
          // Logic here 
      });
      
  11. 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:

  1. saving
  2. creating or updating (depending on the action)
  3. created or updated (depending on the action)
  4. saved

For deletions:

  1. deleting
  2. deleted

For soft-deletion restoration:

  1. restoring
  2. 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.