← Back to blog

FROM THE BLOG

Track Create, Update and Delete Activity in Laravel

Use Eloquent model events to build an activity trail that records what changed, which model changed and who made the change.

Flat illustration of an activity log with create, update and delete events

An activity log answers practical questions: who changed a record, when did it change, and what kind of action occurred? Eloquent model events provide a central place to capture creates, updates and deletes without repeating logging code in every controller.

Design the log record

Create an activity_logs table with an action, model type, model ID, JSON changes, nullable actor ID and timestamps. A nullable actor allows scheduled jobs and other system actions to be recorded. Keep the log model itself out of the logging hook to avoid recursion.

Listen to model events

Use a model observer or a reusable trait for the models you want to audit. The created, updated and deleted events run after their respective operations, so the record already has an ID when a create event is logged.

protected static function booted(): void
{
    static::created(fn (self $model) => ActivityLog::create([
        'action' => 'created',
        'model_type' => $model::class,
        'model_id' => $model->getKey(),
        'performed_by' => auth()->id(),
    ]));

    static::updated(fn (self $model) => ActivityLog::create([
        'action' => 'updated',
        'model_type' => $model::class,
        'model_id' => $model->getKey(),
        'changes' => $model->getChanges(),
        'performed_by' => auth()->id(),
    ]));
}

Register a deleted callback in the same way for deletion events. Cast the log’s changes field to an array, and allow only the attributes you write through ActivityLog::create() in its fillable list. Avoid logging passwords, tokens or other sensitive fields; define an explicit allowlist of fields for your audit trail.

Important: mass updates and deletes performed directly through an Eloquent query do not dispatch individual model events, because the models are never retrieved. Use per-model operations when the audit log must capture every record. The Laravel Eloquent events guide explains the event lifecycle.

Based on: Abdo Host’s original article on Medium.