2017 © Pedro Peláez
 

library eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

image

sbarre/eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

  • Friday, February 19, 2016
  • by sbarre
  • Repository
  • 7 Watchers
  • 28 Stars
  • 342 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 9 Forks
  • 10 Open issues
  • 7 Versions
  • 66 % Grown

The README.md

Eloquent Versioned

Adds transparent versioning support to Laravel 5.2's Eloquent ORM., (*1)

WARNING: This repository is currently super-duper experimental. I will gladly accept pull requests and issues, but you probably shouldn't use this in production, and the interfaces may change without notice (although major changes will bump the version)., (*2)

It was also recently updated to bring global scopes in line with Laravel 5.2 so if you are not yet on 5.2, stick with release 0.0.7., (*3)

When using this trait (and with a table that includes the required fields), saving your model will actually create a new row instead, and increment the version number., (*4)

Using global scopes, old versions are ignored in the standard ORM operations (selects, updates, deletes) and relations (hasOne, hasMany, belongsTo, etc)., (*5)

The package also provides some special methods to include old versions in queries (or only query old versions) which can be useful for showing a model's history, or the like., (*6)

Installation

To add via Composer:, (*7)

composer require sbarre/eloquent-versioned --no-dev

Use the --no-dev flag to avoid pulling down all the testing dependencies (like the entire Laravel framework)., (*8)

Migrations

Versioned models require that your database table contain 3 fields to handle the versioning., (*9)

If you are creating a new table, or if you are changing an existing table, include the following lines in the up() method of the migration:, (*10)

$table->integer('model_id')->unsigned()->default(1);
$table->integer('version')->unsigned()->default(1);
$table->integer('is_current_version')->unsigned()->default(1);
$table->index('is_current_version');
$table->index('model_id');
$table->index('version');

If your migration was altering an existing table, you should include these lines in the down() method of your migration:, (*11)

$table->dropColumn(['model_id','version','is_current_version']);
$table->dropIndex(['model_id','version','is_current_version']);

Caveats

If you change the constants in EloquentVersioned\VersionedBuilder to rename the columns, remember to change them in your migrations as well., (*12)

Usage

In your Eloquent model class, start by adding the use statement for the Trait:, (*13)

use EloquentVersioned\Traits\Versioned;

When the trait boots it will apply the proper scope, and provides overrides on various Eloquent methods to support versioned records., (*14)

Once the trait is applied, you use your models as usual, with the standard queries behaving as usual., (*15)

$project = Project::create([
    'name' => 'Project Name',
    'description' => 'Project description goes here'
])->fresh();

print_r($project->toArray());

This would then output (for example):, (*16)

Array
(
    [id] => 1
    [version] => 1
    [name] => Project Name
    [description] => Project description goes here
    [created_at] => 2015-05-24 17:16:05
    [updated_at] => 2015-05-24 17:16:05
)

The actual database row looks like this:, (*17)

Array
(
    [id] => 1
    [model_id] => 1
    [version] => 1
    [is_current_version] => 1
    [name] => Updated project Name
    [description] => Project description goes here
    [created_at] => 2015-05-24 17:16:05
    [updated_at] => 2015-05-24 17:16:05
)

Then if you change the model and save:, (*18)

$project->name = 'Updated project name';
$project->save();

print_r($project->toArray());

This would then output:, (*19)

Array
(
    [id] => 1
    [version] => 2
    [name] => Updated project Name
    [description] => Project description goes here
    [created_at] => 2015-05-24 17:16:05
    [updated_at] => 2015-05-24 17:16:45
)

The model mutates the model_id column into id, and hides some of the version-specific columns. In reality this is actually the same database row that now looks like this:, (*20)

Array
(
    [id] => 1
    [model_id] => 1
    [version] => 2
    [is_current_version] => 1
    [name] => Updated project Name
    [description] => Project description goes here
    [created_at] => 2015-05-24 17:16:05
    [updated_at] => 2015-05-24 17:16:45
)

While a new row is inserted to save our previous version, which now looks like this:, (*21)

Array
(
    [id] => 2
    [model_id] => 1
    [version] => 1
    [is_current_version] => 0
    [name] => Project Name
    [description] => Project description goes here
    [created_at] => 2015-05-24 17:16:05
    [updated_at] => 2015-05-24 17:16:05
)

So the is_current_version property is what the global scope is applied against, limiting all select queries to only records where is_current_version = 1., (*22)

Calling save() on a model replicates the original version into a new row (with is_current_version = 0), then increments the version_id property on our current model, changes the appropriate timestamps, and saves it., (*23)

If you are making a very minor change to a model and you don't want to create a new version, you can call saveMinor() instead., (*24)

$project->saveMinor(); // doesn't create a new version

Methods for dealing with old versions

If you want to retrieve a list of all versions of a model (or include old versions in a bigger query):, (*25)

$projectVersions = Project::withOldVersions()->find(1);

If run after our example above, this would return an array with 2 models., (*26)

You can also retrieve a list of only old models by using:, (*27)

$oldVersions = Project::onlyOldVersions()->find(1);

Otherwise, the rest of Eloquent's ORM operations should work as usual, including the out-of-the-box relations., (*28)

Methods for moving through a model's versions

If you want to navigate through all of model's versions, in a linked-list manner:, (*29)

$current = Project::find(1);

$previous = $current->getPreviousModel();
$next = $previous->getNextModel();

// $next == $current

If you are at the most recent version, getNextModel() will return null and likewise if you are at the oldest version, getPreviousModel() will return null., (*30)

Support & Roadmap

As indicated at the top, this package is still very experimental and is under active development. The current roadmap includes test coverage and more extensive real-world testing, so pull requests and issues are always welcome!, (*31)

The Versions

19/02 2016

dev-master

9999999-dev https://github.com/sbarre/eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

  Sources   Download

MIT

The Requires

 

The Development Requires

by Sebastien Barre

orm laravel eloquent versioning

19/02 2016

0.1.2

0.1.2.0 https://github.com/sbarre/eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

  Sources   Download

MIT

The Requires

 

The Development Requires

by Sebastien Barre

orm laravel eloquent versioning

16/02 2016

0.1.1

0.1.1.0 https://github.com/sbarre/eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

  Sources   Download

MIT

The Requires

 

The Development Requires

by Sebastien Barre

orm laravel eloquent versioning

16/02 2016

0.1.0

0.1.0.0 https://github.com/sbarre/eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

  Sources   Download

MIT

The Requires

 

The Development Requires

by Sebastien Barre

orm laravel eloquent versioning

16/02 2016

dev-laravel-52

dev-laravel-52 https://github.com/sbarre/eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

  Sources   Download

MIT

The Requires

 

The Development Requires

by Sebastien Barre

orm laravel eloquent versioning

25/05 2015

0.0.7

0.0.7.0 https://github.com/sbarre/eloquent-versioned

Add transparent versioning to Laravel 5's Eloquent ORM

  Sources   Download

MIT

The Requires

 

The Development Requires

by Sebastien Barre

orm laravel eloquent versioning

25/05 2015

0.0.6

0.0.6.0 https://github.com/sbarre/eloquent-versioned

Add transparent versioning to Laravel 5's Eloquent ORM

  Sources   Download

MIT

The Requires

 

by Sebastien Barre

orm laravel eloquent versioning