Keeping revisions of your laravel model data

There’s times where you want to be able to keep a revision history of all the changes that are made to your models, whether it be for accountability reasons or for providing the ability to roll back changes.

In our case, it was both, so I decided to make something generic that would let me to pick and choose which of my models I wanted to have a revision history, and when I decided I wanted one to have a revision history it had to be childs play to add on.

The best option to me seemed to make a new base model, which I would extend from any models I wanted to be revision-able, which lead to creating and naming the package, Revisionable.

It’s pretty simple in the way that it works, basically it compares the models data before and after saving it (to help with getting hooks to the before save and after save timing, I made use of another existing package, Ardent).

If any of the values in the model have changed, a record is inserted into the revisionable table making a note of the model type, id, field name, old value, new value, and the timer hat it occurred.

So now, every time a model is changed that is extending the revisionable model, its revision history is stored, and all I have to do is extend the class, that’s it.

The next step though is to pull that data back out of the database at will.

The package comes with another basic revision model which is what is returned when you ask for a revision history. Since we’re extending the revisionable base model from a range of different models, and we want to keep things quick and easy to setup, it doesn’t make sense to have to add in methods into our models for creating the relationships between models, that’s where Laravels awesome morph functionality comes into play.

public function revisionHistory() {
    return $this->morphMany('\Venturecraft\Revisionable\Revision', 'revisionable');

Having the above in the base revisionable model, lets us then do things like this:

@foreach($user->revisionHistory as $history)
    {{ ucfirst($history->key) }} changed from {{ $history->old_value }} to {{ $history->new_value }}

Which would give you something like:

  • username changed from bob to bobby
  • age changed from 21 to 22
  • city changed from Melbourne to Sydney

You can get the package from packagist here, or feel free to contribute to the github repo to extend it further, there’s still a bit of work to do on it to make it pure schmick.

March 26, 2013

© 2020