The Yesterday gem lets you track changes made in ActiveRecord models. It’s also possible to diff different versions. The big difference with this gem and others (like Papertrail) is, is that it is possible to diff all child objects (has_many, belongs_to & has_and_belongs_to_many) and it’s changes.
www.youtube.com/watch?v=YgtByWlBSdA
Install the gem:
gem install yesterday
And then run the generator in your Rails 3 project:
rails generate yesterday:install
First create model that will hold your changesets:
class Changeset < ActiveRecord::Base include Yesterday::ChangesetBase end
Now assign the models you want to track:
class Contact < ActiveRecord::Base has_many :addresses track_changes :with => :changesets end class Address < ActiveRecord::Base has_many :companies exclude_tracking_for :associations => :companies end
some_contact = Contact.find(10) some_contact.version_number
Viewing a version from an already found active record model:
some_contact = Contact.find(10) some_contact.version(2)
Or using in a scope chain:
Contact.where(:first_name => 'foo').last.version(3)
Both of the above examples will return a Yesterday::VersionedObject
contact = Contact.create :first_name => 'foo' contact.update_attribute :first_name => 'baz' puts contact.version(1).first_name # -> foo puts contact.version(2).first_name # -> baz
Use version numbers two compare two versions:
contact = Contact.create :first_name => 'foo' contact.update_attribute :first_name => 'baz' diff = contact.diff_version(1, 2) puts diff.first_name.current # -> baz puts diff.first_name.previous # -> foo
Diff’s within associations:
address = [Address.new(:address => 'blah')] contact = Contact.new :first_name => 'foo' contact.addresses = [address] contact.save! contact.addresses.first.address = 'blahblah' contact.save! diff = contact.diff_version(1, 2) puts diff.addresses.first.address.current # -> blahblah puts diff.addresses.first.address.previous # -> foo
To check if associations are created, just use the created_ prefix before the appropiate association:
contact.addresses.first.created?
Or, for removed associations:
contact.addresses.first.destroyed?
Or, just modified:
contact.addresses.first.modified?
Or… nothing:
contact.addresses.first.unmodified?
Use it and have fun with it! Comments, cakes and hugs are welcome! Just stick to the license!
Copyright 2011, Diederick Lawson - Altovista. Released under the FreeBSD license.