PHPackages                             anonimowybanan/model-diff - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. anonimowybanan/model-diff

ActiveLibrary[Database &amp; ORM](/categories/database)

anonimowybanan/model-diff
=========================

Laravel package for tracking and comparing Eloquent model changes

01PHPCI passing

Since Apr 17Pushed 3mo agoCompare

[ Source](https://github.com/AnonimowyBanan/ModelDiff)[ Packagist](https://packagist.org/packages/anonimowybanan/model-diff)[ RSS](/packages/anonimowybanan-model-diff/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

ModelDiff
=========

[](#modeldiff)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d9563bcf9d3975845b471d6139f2e7254b12bf57148f91cc0acfa488ae6d0946/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616e6f6e696d6f777962616e616e2f6d6f64656c2d646966662e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/anonimowybanan/model-diff)[![Total Downloads](https://camo.githubusercontent.com/4bd4d0ab38e044bec1fa16cfc3d91ce9eb8bdc18695cca3035c1a247ab95a3f1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616e6f6e696d6f777962616e616e2f6d6f64656c2d646966662e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/anonimowybanan/model-diff)[![License](https://camo.githubusercontent.com/e0a81f43d27321b643f854fd29e039c17aab7d427dba896dc759b87a6d4a344c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f616e6f6e696d6f777962616e616e2f6d6f64656c2d646966662e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/anonimowybanan/model-diff)

Track and compare Eloquent model changes with ease. ModelDiff automatically logs field-level modifications, supports batched change tracking, and provides a powerful query API for browsing change history.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10+

Installation
------------

[](#installation)

You can install the package via Composer:

```
composer require anonimowybanan/model-diff
```

Publish the config file and migration:

```
php artisan vendor:publish --provider="AnonimowyBanan\ModelDiff\ModelDiffServiceProvider"
```

Run the migration:

```
php artisan migrate
```

Quick Start
-----------

[](#quick-start)

Add the `TracksChanges` trait to any Eloquent model you want to track:

```
use AnonimowyBanan\ModelDiff\Traits\TracksChanges;

class User extends Model
{
    use TracksChanges;
}
```

That's it. Every time the model is updated, changes are automatically logged to the database.

```
$user = User::create(['name' => 'John', 'email' => 'john@example.com']);

$user->update(['name' => 'Jane']);

// A change log entry is now stored for the 'name' field
```

Usage
-----

[](#usage)

### Comparing Changes

[](#comparing-changes)

Compare the current dirty state of a model against its persisted state:

```
$user = User::find(1);
$user->name = 'Jane';

$diff = $user->getDiff();

if ($diff->hasChanges()) {
    $diff->changedFields(); // ['name']

    $change = $diff->fieldChange('name');
    $change->oldValue; // 'John'
    $change->newValue; // 'Jane'
}
```

You can also compare two separate model instances:

```
use AnonimowyBanan\ModelDiff\Facades\ModelDiff;

$diff = ModelDiff::compareModels($oldUser, $newUser);
```

### Querying Change History

[](#querying-change-history)

```
use AnonimowyBanan\ModelDiff\Facades\ModelDiff;

// All changes for a model (newest first)
$history = ModelDiff::historyFor($user)->get();

// Changes grouped by batch (all fields changed in a single save)
$grouped = ModelDiff::groupedHistoryFor($user);
```

### Query Scopes

[](#query-scopes)

The `ChangeLog` model provides several useful scopes:

```
use AnonimowyBanan\ModelDiff\Models\ChangeLog;

ChangeLog::forModel($user)->get();           // Changes for a specific model
ChangeLog::forModel($user)->forField('name')->get(); // Changes for a specific field
ChangeLog::byUser($userId)->get();           // Changes made by a specific user
ChangeLog::inBatch($batchId)->get();         // Changes from a specific batch
```

### Output Formatting

[](#output-formatting)

```
$diff = $user->getDiff();

// Array format
$diff->toArray();
// [['field' => 'name', 'old' => 'John', 'new' => 'Jane']]

// Table format (useful for Artisan commands)
$diff->toTable();
// [['Field', 'Old Value', 'New Value'], ['name', 'John', 'Jane']]
```

### Manual Logging

[](#manual-logging)

If you prefer to log changes manually, disable auto-logging and call `logDiff` yourself:

```
config(['model-diff.auto_log' => false]);

$diff = app('model-diff')->compare($user);

app('model-diff')->logDiff($user, $diff, ['reason' => 'Admin override']);
```

### Batch Tracking

[](#batch-tracking)

When multiple fields change in a single `update()`, they share the same batch UUID:

```
$user->update(['name' => 'Jane', 'email' => 'jane@example.com']);

$logs = ChangeLog::forModel($user)->get();
$logs[0]->batch === $logs[1]->batch; // true
```

Configuration
-------------

[](#configuration)

After publishing, the config file is located at `config/model-diff.php`.

### Global Ignored Fields

[](#global-ignored-fields)

Fields that are never tracked across all models:

```
'ignored_fields' => ['password', 'remember_token', 'updated_at', 'created_at'],
```

### Auto Logging

[](#auto-logging)

Toggle automatic change logging on model save:

```
'auto_log' => true,
```

### User Resolver

[](#user-resolver)

Customize how the current user is resolved for change attribution:

```
'user_resolver' => fn () => auth()->id(),

// Or use a callable class
'user_resolver' => App\Services\CustomUserResolver::class,
```

### Per-Model Configuration

[](#per-model-configuration)

Define tracked or ignored fields on a per-model basis:

```
'models' => [
    // Whitelist: track ONLY these fields
    App\Models\User::class => [
        'only' => ['name', 'email'],
    ],

    // Blacklist: ignore these fields (in addition to global ignored)
    App\Models\Post::class => [
        'ignored' => ['view_count', 'cache_key'],
    ],
],
```

### Trait-Level Overrides

[](#trait-level-overrides)

Override tracked or ignored fields directly on the model:

```
class User extends Model
{
    use TracksChanges;

    public function getTrackedFields(): ?array
    {
        return ['name', 'email']; // Only track these fields
    }

    public function getIgnoredFields(): array
    {
        return ['api_token']; // Ignore in addition to global list
    }
}
```

### Custom Table Name

[](#custom-table-name)

Change the database table used for storing change logs:

```
'table_name' => 'model_diff_change_logs',
```

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

18

—

LowBetter than 7% of packages

Maintenance54

Moderate activity, may be stable

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/67584450?v=4)[Robert Halama](/maintainers/AnonimowyBanan)[@AnonimowyBanan](https://github.com/AnonimowyBanan)

---

Top Contributors

[![AnonimowyBanan](https://avatars.githubusercontent.com/u/67584450?v=4)](https://github.com/AnonimowyBanan "AnonimowyBanan (10 commits)")

### Embed Badge

![Health badge](/badges/anonimowybanan-model-diff/health.svg)

```
[![Health](https://phpackages.com/badges/anonimowybanan-model-diff/health.svg)](https://phpackages.com/packages/anonimowybanan-model-diff)
```

###  Alternatives

[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k117.2M118](/packages/jdorn-sql-formatter)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8351.6M87](/packages/propel-propel1)[jfelder/oracledb

Oracle DB driver for Laravel

11518.4k](/packages/jfelder-oracledb)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
