patoui / model-history
A Laravel package to track model changes
Requires
- php: ^8.3
- illuminate/contracts: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9||^3.0
- laravel/pint: ^1.14
- mockery/mockery: ^1.6
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
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.