Skip to content
This repository has been archived by the owner. It is now read-only.
Audit activerecord models like a boss (and works with rails 4!)
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
app/models/espinita
bin initial commit Oct 31, 2013
config initial commit Oct 31, 2013
coverage remove gemfile.locks from gemfiles Aug 3, 2014
db/migrate
gemfiles
lib enable/disable audits block Oct 18, 2015
spec
.coveralls.yml coveralls support Oct 31, 2013
.gitignore remove gemfile.locks from gemfiles Aug 3, 2014
.travis.yml Simplify travis-ci Ruby versioning Sep 22, 2014
Appraisals
Gemfile fix audit_destroy on audit behavior Aug 3, 2014
Gemfile.lock update deps May 24, 2015
MIT-LICENSE
README.md Added documentation for history and restore May 13, 2015
Rakefile fix audit_destroy on audit behavior Aug 3, 2014
espinita.gemspec Added Timecop to test history consistently Mar 29, 2015
espinita.jpg initial commit Oct 31, 2013

README.md

Espinita

Build Status Dependency Status Coverage Status Code Climate

Audits activerecord models like a boss

Alt text

Audit activerecord models like a boss. Tested in rails 4.0 / 4.1 and ruby 1.9.3 / 2.0.0.

This project is heavily based in audited gem.

Installation

In your gemfile

gem "espinita"

In console

$ rake espinita:install:migrations
$ rake db:migrate

Usage

class Post < ActiveRecord::Base
  auditable
end

@post.create(title: "an awesome blog post" )

Espinita will create an audit by default on creation , edition and destroy:

@post.audits.size #=> 1

Espinita provides options to include or exclude columns to trigger the creation of audit.

class Post < ActiveRecord::Base
  auditable only: [:title] # except: [:some_column]
end

And lets you declare the callbacks you want for audit creation:

class Post < ActiveRecord::Base
  auditable on: [:create]  # on: [:create, :update]
end

You can find the audits records easily:

@post.audits.first #=>  #<Espinita::Audit id: 1, auditable_id: 1, auditable_type: "Post", user_id: 1, user_type: "User", audited_changes: {"title"=>[nil, "MyString"], "created_at"=>[nil, 2013-10-30 15:50:14 UTC], "updated_at"=>[nil, 2013-10-30 15:50:14 UTC], "id"=>[nil, 1]}

Espinita will save the model changes in a serialized column called audited_changes:

@post.audits.first.audited_changes #=> {"title"=>[nil, "MyString"], "created_at"=>[nil, 2013-10-30 15:50:14 UTC], "updated_at"=>[nil, 2013-10-30 15:50:14 UTC], "id"=>[nil, 1]}

Espinita will detect the current user when records saved from rails controllers. By default Espinita uses current_user method but you can change it:

Espinita.current_user_method = :authenticated_user

History and Restoration

If you just want a summary of changes for a particular attribute or attributes of a model, you can use the history_from_audits_for method.

my_model.history_from_audits_for(:name)
=> [{changes: {name: "Arglebargle"}, changed_at: 2015-05-13 15:28:22 -0700},
{changes: {name: "Baz"}, changed_at: 2014-05-13 15:28:22 -0700},
{changes: {name: "Foo"}, changed_at: 2013-05-13 15:28:22 -0700}]

You can also provide an array of attributes to get a single history for all of them.

my_model.history_from_audits_for([:name, :settings])
=> [{changes: {name: "Arglebargle", settings: "Waffles"}, changed_at: 2015-05-13 15:28:22 -0700},
{changes: {name: "Baz"}, changed_at: 2014-05-13 15:28:22 -0700}]

Sometimes it's useful to roll a record back to a particular point in time, such as if it was accidentally modified. For this, the restore_attributes! method is provided.

As with history_from_audits_for, this can be used with a single attribute or an array of attributes.

model.name
=> "Baz"
model.settings
=> ""

model.history_from_audits_for([:name, :settings])
=> [{:changes=>{:name=>"Baz", :settings=>""}, :changed_at=>2015-05-03 15:33:58 -0700},
 {:changes=>{:name=>"Arglebargle", :settings=>"IHOP"}, :changed_at=>2015-03-24 15:33:58 -0700},
 {:changes=>{:name=>"Walrus"}, :changed_at=>2014-05-13 15:33:58 -0700}]

model.restore_attributes!([:name, :settings], DateTime.now - 57.days)
=> true

model.name
=> "Walrus"
model.settings
=> "MyText"

The restore_attributes! method returns true if it makes a change to the model, or false if there is no resulting change.

Note: this uses update_attributes() to do the rollback, so it will skip validations, but will trigger any callbacks that you may have in place.

You can’t perform that action at this time.