PHPackages                             thumbrise/laravel-versioned-model - 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. [Framework](/categories/framework)
4. /
5. thumbrise/laravel-versioned-model

AbandonedArchivedLibrary[Framework](/categories/framework)

thumbrise/laravel-versioned-model
=================================

Versioned model for Laravel.

v1.0.0(5mo ago)10[1 PRs](https://github.com/thumbrise/laravel-versioned-model/pulls)MITPHPPHP &gt;=8.1CI passing

Since Jan 20Pushed 5mo agoCompare

[ Source](https://github.com/thumbrise/laravel-versioned-model)[ Packagist](https://packagist.org/packages/thumbrise/laravel-versioned-model)[ RSS](/packages/thumbrise-laravel-versioned-model/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (7)Versions (4)Used By (0)

Laravel Versioned Model
=======================

[](#laravel-versioned-model)

[![Latest Version on Packagist](https://camo.githubusercontent.com/c3910983b700e204cd5d2ec2a4aecdb37fb5890586826c3d403c5261a2fa2d9e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7468756d62726973652f6c61726176656c2d76657273696f6e65642d6d6f64656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/thumbrise/laravel-versioned-model)[![GitHub Tests Action Status](https://camo.githubusercontent.com/35cae1c750936f26969d3d326f1044a66891bb683f68cca7b3c169cdfef9aa16/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7468756d62726973652f6c61726176656c2d76657273696f6e65642d6d6f64656c2f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/thumbrise/laravel-versioned-model/actions?query=workflow%3Atests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/50aae51123558594bbc28b08ad2690e6c99adc3b055510ff7a99995917a4f18c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7468756d62726973652f6c61726176656c2d76657273696f6e65642d6d6f64656c2f636f64652d7175616c6974792e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/thumbrise/laravel-versioned-model/actions?query=workflow%3Acode-quality+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/4bbc01b77e83f63c86d4574769cc3645fbfbcdd2e92bfb468f0315724413b5de/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7468756d62726973652f6c61726176656c2d76657273696f6e65642d6d6f64656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/thumbrise/laravel-versioned-model)[![PHPStan Level](https://camo.githubusercontent.com/fa7d257d0c5c1cf237ac3490ef3a5561626b17fcb0a8547c01b0bb8746554e60/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230392d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](phpstan.neon)

A powerful and easy-to-use Laravel package that provides automatic versioning for your Eloquent models. Track changes, create snapshots, compare versions, and revert to previous states with a simple API.

---

📖 **[Documentation](#documentation)** • 🤝 **[Contributing](docs/CONTRIBUTING.md)** • 📋 **[Changelog](CHANGELOG.md)** • 📜 **[License](#license)**

---

Features
--------

[](#features)

✨ **Full Snapshot Versioning** - Store complete model state at each version
🔄 **Automatic Version Tracking** - Track who, when, and what changed
📊 **Diff Comparison** - Compare any two versions to see what changed
⏮️ **Version Rollback** - Easily revert to any previous version
📝 **Field History** - Get complete history of changes for specific fields
🔒 **Transaction Safety** - All operations wrapped in database transactions
🎯 **Selective Tracking** - Exclude specific fields from versioning
⚡ **Performance Optimized** - Uses `latestOfMany()` for efficient queries
🔗 **Polymorphic Relations** - Track changes made by any model (users, admins, etc.)

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

[](#requirements)

- PHP 8.1 or higher
- Laravel 10.x or 11.x

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

[](#installation)

You can install the package via composer:

```
composer require thumbrise/laravel-versioned-model
```

Publish and run the migrations:

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

Usage
-----

[](#usage)

### Basic Setup

[](#basic-setup)

Add the `HasVersions` trait to your model:

```
use Illuminate\Database\Eloquent\Model;
use Thumbrise\LaravelVersionedModel\Traits\HasVersions;

class Article extends Model
{
    use HasVersions;

    protected $fillable = ['title', 'content', 'status'];
}
```

### Creating Versions

[](#creating-versions)

Use the `updateVersioned()` method instead of regular `update()` to automatically create a version:

```
$article = Article::create([
    'title' => 'My First Article',
    'content' => 'Initial content',
    'status' => 'draft'
]);

// Update and create a version snapshot
$article->updateVersioned([
    'title' => 'My Updated Article',
    'content' => 'Updated content'
]);

// Each update creates a new version
$article->updateVersioned(['status' => 'published']);
```

### Retrieving Versions

[](#retrieving-versions)

```
// Get all versions
$versions = $article->getVersions();

// Get a specific version
$version = $article->getVersion(2);

// Get the latest version
$latestVersion = $article->getLatestVersion();

// Access version data
echo $version->version;        // Version number
echo $version->snapshot;       // Full model snapshot as array
echo $version->created_at;     // When this version was created
echo $version->changer;        // Who made the change (authenticated user)
```

### Comparing Versions

[](#comparing-versions)

Get the differences between any two versions:

```
// Compare version 1 and version 2
$diff = $article->getDiff(1, 2);

// Compare version 1 with current state
$diff = $article->getDiff(1, null);

// Compare initial state (before first version) with current state
$diff = $article->getDiff(null, null);

// Result format:
// [
//     'title' => [
//         'old' => 'My First Article',
//         'new' => 'My Updated Article'
//     ],
//     'content' => [
//         'old' => 'Initial content',
//         'new' => 'Updated content'
//     ]
// ]
```

### Reverting to Previous Versions

[](#reverting-to-previous-versions)

```
// Revert to version 1
$article->revertToVersion(1);

// This creates a new version with the old data
echo $article->title; // Back to the original title
```

### Field History

[](#field-history)

Track the complete history of changes for specific fields:

```
// Get history for a single field
$history = $article->getFieldHistory('status');

// Result:
// [
//     [
//         'version' => 1,
//         'value' => 'draft',
//         'changed_at' => Carbon instance,
//         'changer' => User model
//     ],
//     [
//         'version' => 2,
//         'value' => 'published',
//         'changed_at' => Carbon instance,
//         'changer' => User model
//     ]
// ]

// Get history for multiple fields
$history = $article->getFieldsHistory(['title', 'status']);
```

### Excluding Fields from Versioning

[](#excluding-fields-from-versioning)

By default, `created_at` and `updated_at` are excluded. You can exclude additional fields:

```
class Article extends Model
{
    use HasVersions;

    protected static function getExcludedVersionFields(): array
    {
        return ['view_count', 'last_viewed_at'];
    }
}
```

### Custom Changer Resolution

[](#custom-changer-resolution)

By default, the package tracks changes made by the authenticated user. You can customize this:

```
class Article extends Model
{
    use HasVersions;

    protected static function resolveChanger(): ?Model
    {
        // Track by admin instead of regular user
        return auth()->guard('admin')->user();

        // Or use a different model entirely
        return SystemLog::getCurrentActor();
    }
}
```

### Using Relationships

[](#using-relationships)

```
// Eager load versions
$article = Article::with('versions')->find(1);

// Eager load only the latest version
$article = Article::with('latestVersion')->find(1);

// Query versions
$article->versions()
    ->where('created_at', '>', now()->subDays(7))
    ->get();
```

Advanced Usage
--------------

[](#advanced-usage)

### Manual Version Creation

[](#manual-version-creation)

While `updateVersioned()` is the recommended approach, you can also create versions manually:

```
use Thumbrise\LaravelVersionedModel\Models\ModelVersion;

ModelVersion::create([
    'model_type' => $article->getMorphClass(),
    'model_id' => $article->getKey(),
    'changer_type' => auth()->user()?->getMorphClass(),
    'changer_id' => auth()->id(),
    'version' => 1,
    'snapshot' => [
        'title' => 'Custom Title',
        'content' => 'Custom Content'
    ]
]);
```

### Accessing Version Relationships

[](#accessing-version-relationships)

```
$version = $article->getVersion(1);

// Get the model this version belongs to
$model = $version->model; // Returns Article instance

// Get who made this change
$user = $version->changer; // Returns User instance (or null)
```

Database Schema
---------------

[](#database-schema)

The package creates a `model_versions` table with the following structure:

ColumnTypeDescriptionidbigintPrimary keymodel\_typestringPolymorphic type of the versioned modelmodel\_idbigintID of the versioned modelchanger\_typestringPolymorphic type of who made the change (nullable)changer\_idbigintID of who made the change (nullable)versionintegerSequential version numbersnapshotjson/jsonbComplete snapshot of model statecreated\_attimestampWhen this version was createdIndexes:

- `(model_type, model_id, version)` - Unique constraint
- `(model_type, model_id)` - Query optimization
- `(changer_type, changer_id)` - Polymorphic relation

Testing
-------

[](#testing)

```
composer test
```

Run code quality checks:

```
composer lint
```

Fix code style:

```
composer fmt
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](docs/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

If you discover a security vulnerability, please email Ruslan Kokoev at . All security vulnerabilities will be promptly addressed.

Credits
-------

[](#credits)

- [Ruslan Kokoev](https://github.com/thumbrise)
- [All Contributors](../../contributors)

License
-------

[](#license)

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

###  Health Score

33

—

LowBetter than 72% of packages

Maintenance71

Regular maintenance activity

Popularity2

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 92.9% 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.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

166d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/61841057?v=4)[Ruslan Kokoev](/maintainers/thumbrise)[@thumbrise](https://github.com/thumbrise)

---

Top Contributors

[![thumbrise](https://avatars.githubusercontent.com/u/61841057?v=4)](https://github.com/thumbrise "thumbrise (13 commits)")[![semantic-release-bot](https://avatars.githubusercontent.com/u/32174276?v=4)](https://github.com/semantic-release-bot "semantic-release-bot (1 commits)")

---

Tags

frameworklaravel

###  Code Quality

Static AnalysisPHPStan

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/thumbrise-laravel-versioned-model/health.svg)

```
[![Health](https://phpackages.com/badges/thumbrise-laravel-versioned-model/health.svg)](https://phpackages.com/packages/thumbrise-laravel-versioned-model)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M201](/packages/laravel-ai)[spatie/laravel-health

Monitor the health of a Laravel application

87512.0M167](/packages/spatie-laravel-health)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.0k](/packages/simplestats-io-laravel-client)[api-platform/laravel

API Platform support for Laravel

58171.6k14](/packages/api-platform-laravel)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

44855.7k](/packages/harris21-laravel-fuse)

PHPackages © 2026

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