Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

How to Log Model Changes with Spatie Laravel Activitylog

When a Laravel Eloquent model changes, Spatie Laravel Activitylog can save a record of that event in the activity_log database table. An Eloquent model represents a database record, such as a product or user. The saved activity can show which model changed and, when configured, which attribute values changed.

Add the package’s LogsActivity trait to a model to record its create, update, and delete events. Then configure the model to capture the fields you care about. The examples follow the package’s version 5 documentation. They show how to install it, choose which fields and events to log, and read the saved changes.

Install the package and migration

Install Activitylog with Composer, publish its database migration, and run that migration:

composer require spatie/laravel-activitylog

php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="activitylog-migrations"

php artisan migrate

The migration creates the activity_log table. Its default subject_id and causer_id columns assume integer IDs. If your models use UUIDs or another ID format, adjust those columns in the published migration before running it. The package’s installation instructions document the commands and the ID-format caveat.

Add logging to an Eloquent model

Use LogsActivity on each model whose events you want to record. By default, the trait logs model creation, updates, and deletion, but it does not record the changed attribute values.

use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Models\Concerns\LogsActivity;

class Product extends Model
{
    use LogsActivity;
}

To log attribute values, implement getActivitylogOptions() and return a LogOptions instance. This example records changes to a product’s name and price:

use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Support\LogOptions;
use Spatie\Activitylog\Models\Concerns\LogsActivity;

class Product extends Model
{
    use LogsActivity;

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly(['name', 'price'])
            ->logOnlyDirty();
    }
}

logOnly() selects the attributes Activitylog should capture. logOnlyDirty() records only attributes whose values changed in an update. For example, when a request saves a product with a new price but the same name, the update entry includes the price change.

You can use logOnly(['*']) to capture every attribute. For a narrower selection based on which attributes Laravel allows you to set in bulk (mass assignment), use logFillable() for $fillable attributes or logUnguarded() for attributes not listed in $guarded. Choose fields deliberately: logging every attribute also records fields you might not want in an activity history. The model-event documentation describes these options and their combinations.

Choose which events and changes to record

Activitylog records created, updated, and deleted events by default. Set the model’s $recordEvents property to choose the events to include, or use $doNotRecordEvents to exclude specific events. For example, record only creations when later edits and deletions do not belong in the history.

Activitylog can create an update entry when Laravel changes only the updated_at timestamp. To prevent an entry when only specified attributes change, add dontLogIfAttributesChangedOnly(). For example:

return LogOptions::defaults()
    ->logOnly(['name', 'price', 'updated_at'])
    ->logOnlyDirty()
    ->dontLogIfAttributesChangedOnly(['updated_at']);

This still records changes to name or price; it suppresses an update when updated_at is the only changed attribute. Check which fields your model logs before applying this rule, because its behavior depends on the attributes in the options.

You can also name a model’s log with useLogName() and customize event descriptions with setDescriptionForEvent(). For example, a description callback can turn the event name into a message that fits your application’s activity history. Activitylog supports dot notation in logOnly() for an attribute on a directly related model, and arrow notation for a specific key in a JSON column.

Read the saved attribute values

An activity entry’s attribute_changes value contains an attributes array for the new values and an old array for the previous values. When a product’s price changes, the code that displays the activity can read those arrays to show the new price and its previous price. The package’s introduction describes the activity records and their change data.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *