patoui/model-history

A Laravel package to track model changes

0.0.1 2025-05-25 13:52 UTC

This package is auto-updated.

Last update: 2025-06-16 23:41:34 UTC


README

A Laravel package that allows you to track changes to your Eloquent models (history) in an opt-in fashion. The package provides extensibility, so you can store changes in your preferred storage system.

โœจ Features

  • Opt-in tracking: Models choose to track changes by using a trait
  • Tracks creation and updates: Captures both model creation and modification events
  • Extensibility: Use the default Eloquent implementation or create your own
  • Configurable: Configuration available for additional control

๐Ÿ“ฆ Installation

You can install the package via composer:

composer require patoui/model-history

Optionally, you can publish the config file with:

php artisan vendor:publish --tag="model-history-config"

Optionally, you can publish and run the migrations with:

php artisan vendor:publish --tag="model-history-migrations"
php artisan migrate

You can publish both config and migrations at once with:

php artisan vendor:publish --provider="Patoui\ModelHistory\ModelHistoryServiceProvider"

โš™๏ธ Configuration

After publishing the config file, you can customize the package behavior by editing config/model-history.php.

๐ŸŽฏ Customizing the model history

You can customize which model is used for storing changes:

'model' => \App\Models\ModelHistory::class,

๐Ÿšซ Customizing Excluded Properties

You can customize which properties are excluded from the model history by modifying the exclude_properties array in your published config file. For example, if you want to also exclude password fields and any _token fields:

'exclude_properties' => [
    'id',
    'created_at',
    'updated_at',
    'deleted_at',
    'password',
    'remember_token',
    '_token',
],

๐Ÿ”ง Model configuration

You may add an additional property to the model to override the default configuration of excluded properties

protected array $modelHistoryExcludedProperties = ['password'];

๐Ÿš€ Usage

๐Ÿ“š Basic Usage

To start tracking changes for a model, simply add the TrackModelHistory trait and the TrackModelHistoryContract interface:

use Illuminate\Database\Eloquent\Model;
use Patoui\ModelHistory\Contracts\TrackModelHistoryContract;
use Patoui\ModelHistory\Traits\TrackModelHistory;

class User extends Model implements TrackModelHistoryContract
{
    use TrackModelHistory;
}

Now any changes to this model will be automatically tracked:

// Creation is tracked
$user = User::create([
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

// Updates are tracked
$user->update(['name' => 'Jane Doe']);

๐Ÿ—„๏ธ Using non-Eloquent storage

This package provides a ModelHistoryRepositoryContract so you may implement your own repository. Once implemented you can simply override the registered singleton in your app service provider

$this->app->singleton(ModelHistoryRepositoryContract::class, MyNewChangeRepository::class);

๐Ÿ  Using ClickHouse

Here's an example using ClickHouse with the Laravel ClickHouse package.

First, install the Laravel ClickHouse package:

composer require glushkovds/phpclickhouse-laravel

Complete the setup from the package.

Create a migration for the changes table:

<?php

declare(strict_types=1);

use PhpClickHouseLaravel\RawColumn;
use PhpClickHouseLaravel\Migration;
use PhpClickHouseSchemaBuilder\Tables\MergeTree;

return new class extends Migration
{
    public function up(): void
    {
        static::createMergeTree('model_histories', fn (MergeTree $table) => $table
            ->columns([
                $table->uuid('id')->default(new RawColumn('generateUUIDv4()')),
                $table->string('model_type'),
                $table->string('model_id'),
                $table->string('old'),
                $table->string('new'),
                $table->uInt64('auth_id'),
                $table->datetime('created_at', 3),
            ])->orderBy('created_at')
        );
    }

    public function down(): void
    {
        static::write('DROP TABLE model_histories');
    }
};

Create a ClickHouse model for the model history:

<?php

declare(strict_types=1);

namespace App\Models;

use PhpClickHouseLaravel\BaseModel;

class ModelHistory extends BaseModel
{
    protected $casts = [
        'old' => 'array',
        'new' => 'array',
    ];
}

Now publish the config

php artisan vendor:publish --tag="model-history-config"

Now update the model with your own

'model' => \App\Models\ModelHistory::class,

๐Ÿงช Testing

composer test

๐Ÿ“‹ Changelog

Please see CHANGELOG for more information on what has changed recently.

๐Ÿ‘ฅ Credits

๐Ÿ“„ License

The MIT License (MIT). Please see License File for more information.