Introduction
Eloquent, the ORM included with Laravel, provides a simple and elegant way to work with your database. But its power isn’t limited to just creating, retrieving, updating, and deleting records; it also boasts a feature called model events, which allows you to hook into various points of a model’s lifecycle. In this comprehensive guide, we’ll delve into the world of Eloquent model events, providing you with the understanding you need to harness this feature to its full potential.
Understanding Model Events
Model events are triggered at specific moments in the lifecycle of a model instance. These include events like ‘creating’, ‘created’, ‘updating’, ‘updated’, ‘saving’, ‘saved’, ‘deleting’, ‘deleted’, ‘restoring’, and ‘restored’. You can set up listeners for these events to execute code at any of these points.
For instance, imagine you want to clear a cache whenever a Post is updated. You could hook into the ‘updated’ event for your Post model to do this automatically.
use App\Models\Post; // Make sure to include the appropriate namespace
use Illuminate\Support\Facades\Cache;
Post::updated(function ($post) {
Cache::forget("posts_cache");
});
Registering Event Listeners
To listen for model events, you can either define them inside your model or within an event service provider. Inside your model, you may use the boot method to attach your event listeners.
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
class Post extends Model
{
protected static function boot()
{
parent::boot();
static::created(function ($post) {
Log::info('Post created: ' . $post->title);
});
}
}
Alternatively, you can use an EventServiceProvider to clean up your model’s code. This is where you can define listeners for your model events.
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
'App\Events\SomeEvent' => [
'App\Listeners\SomeListener',
],
'eloquent.created:App\Post' => [
'App\Listeners\EmailPostCreatedNotification',
],
];
}
Event Observers
For those who prefer to keep their models lean and focused, Eloquent provides observers. An observer class can hold listener methods for multiple event types. Below is an example of an observer class for our Post model.
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
class PostObserver
{
public function created(Post $post)
{
// Handle the "created" event.
Log::info('Post created: ' . $post->title);
}
public function updated(Post $post)
{
// Handle the "updated" event.
Cache::forget("posts_cache");
}
}
After defining your observer, you need to register it within the boot method of a service provider, preferably EventServiceProvider.
public function boot()
{
Post::observe(PostObserver::class);
}
Cancelling Events
Sometimes you may wish to abort an event operation, such as preventing a model from being saved or deleted. To do this, you can return false from your event’s listener.
Post::deleting(function ($post) {
if ($post->is_locked) {
return false;
}
});
Using Model Dispatch Methods
Laravel 5.5 introduced the dispatch methods for model events, which simplifies the process of firing custom events for your models. You can call these methods directly on your model instances when you need to trigger events manually.
$post->dispatchesEvents = [
'saving' => PostSaving::class,
'saved' => PostSaved::class,
];
$post->save();
Custom Events
You are not limited to the default Eloquent events. Eloquent’s model has a method called fireModelEvent
that allows you to create and handle custom events.
protected function fireCustomEvent()
{
if ($this->fireModelEvent('customEvent') === false) {
return false;
}
// Custom logic here
}
Events and Queues
Intensive tasks triggered through model events, like sending emails, can be queued up to improve your application’s performance. You can do this easily by implementing the ShouldQueue
interface in your event listener.
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class SomeIntensiveTaskListener implements ShouldQueue
{
use InteractsWithQueue;
public function handle()
{
// Implement handle() with your logic.
}
}
See also:
- Laravel Queue System: Explained with Examples
- How to use MailGun to send email in Laravel
- Streaming Results Lazily in Laravel Query Builder: Tutorial & Examples
Conclusion
Model events in Eloquent are powerful tools for maintaining clean code and reactivity within your application. By efficiently utilizing these events, you can keep your controllers slim and models clean, leading to an organized codebase. Don’t shy away from using these events; they can greatly improve your workflow and application logic.