Reputation: 938
I need to generate a function to call after or before save() or update() but i don't know how to do. I think I need a callback from save() update() but I don't know how to do. Thanks
Upvotes: 92
Views: 169625
Reputation: 800
This only works after an event happened on your model.
Create an observer for your model
php artisan make:observer UserObserver --model=User
this will create an event observer on your model
class UserObserver
{
/**
* Handle the User "created" event.
*
* @param \App\Models\User $user
* @return void
*/
public function created(User $user)
{
//
}
/**
* Handle the User "updated" event.
*
* @param \App\Models\User $user
* @return void
*/
public function updated(User $user)
{
//
}
/**
* Handle the User "deleted" event.
*
* @param \App\Models\User $user
* @return void
*/
public function deleted(User $user)
{
//
}
/**
* Handle the User "forceDeleted" event.
*
* @param \App\Models\User $user
* @return void
*/
public function forceDeleted(User $user)
{
//
}
}
You must register this observer in the boot method on one of your ServiceProviders preferably the AppServiceProvider
// App\Providers\AppServiceProvider.php
public function boot()
{
User::observe(UserObserver::class);
}
You can register custom events in the static booted method of your model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The "booted" method of the model.
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::created(function ($user) {
//
});
}
}
Available observable events
// Illuminate\Database\Eloquent\Concerns
/**
* Get the observable event names.
*
* @return array
*/
public function getObservableEvents()
{
return array_merge(
[
'retrieved', 'creating', 'created', 'updating', 'updated',
'saving', 'saved', 'restoring', 'restored', 'replicating',
'deleting', 'deleted', 'forceDeleted', 'trashed'
],
$this->observables
);
}
Note from Laravel documentation
When issuing a mass update via Eloquent, the saving, saved, updating, and updated model events will not be fired for the updated models. This is because the models are never actually retrieved when issuing a mass update.
it means that in both method 1 and 2 no event will be fired when you do something like this (mass update users in database directly):
User::where(...)->update(['name' => "ABC"]);
you have to manually get each user from the database and update it to get the events to fire, which is really very bad for performance(DONT do this... unless you know the table has a fixed and small row numbers).
User::where(...)->each(function($user) {
$user->update(['name' => "ABC"]);
});
Upvotes: 40
Reputation: 2018
Create a provider by using this command
php artisan make:provider ProviderClassName
then define the callbacks for models in boot function
Model::created(function($model){
//Do you want to do
});
List of available callbacks:
Model::creating(function($model){});
Model::updated(function($model){});
Model::updating(function($model){});
Model::deleted(function($model){});
Model::deleting(function($model){});
Model::saving(function($model){});
Model::saved(function($model){});
Upvotes: 18
Reputation: 2445
Inside your model, you can add a boot() method which will allow you to manage these events.
For example, having User.php model:
class User extends Model
{
public static function boot()
{
parent::boot();
self::creating(function($model){
// ... code here
});
self::created(function($model){
// ... code here
});
self::updating(function($model){
// ... code here
});
self::updated(function($model){
// ... code here
});
self::deleting(function($model){
// ... code here
});
self::deleted(function($model){
// ... code here
});
}
}
You can review all available events over here: https://laravel.com/docs/5.2/eloquent#events
Upvotes: 222