Yesterday
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 other is, is that it is possible to diff all child objects (has_many, belongs_to & has_and_belongs_to_many) and it’s changes.
Note: work in progress
In the meanwhile: www.youtube.com/watch?v=YgtByWlBSdA
Installation
Install the gem:
gem install yesterday
And then run the generator in your Rails 3 project:
rails generate yesterday:install
Use tracking in your models
class Contact < ActiveRecord::Base
has_many :addresses
track_changes
end
class Address < ActiveRecord::Base
has_many :companies
exclude_tracking_for :associations => :companies
end
Checking version number
some_contact = Contact.find(10)
some_contact.version_number
Viewing historical data of an object
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
Diffing two versions
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?
License and credits
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.