TrackIt

TrackIt is a small gem which helps you keep track of changes in you ActiveRecord models persistently. While ActiveModel::Dirty allows you to keep track on changes only when the change occurs, TrackIt will keep attributes as changed until you decide to clear them.

Getting Started

First you will have to add TrackIt to your gemfile.

gem 'trackit'

Run the bundle install command in order to install the gem.

After the gem was successfully installed you need to run the generator:

rails generate track_it Model attr_a attr_b

This will generate tracking for Model class which inherits from ActiveRecord::Base, and only for attributes attr_a, attr_b.

The last step is migrating your database:

rake db:migrate

You may need to restart your app if it is already running.

Usage

TrackIt provides an interface on your model instance as follows:

model = Model.new

model.tracked.changed?
model.tracked.changed
model.tracked.attr_a_changed?
model.tracked.attr_b_changed?
.
.
.

Each method corresponds to its similiar named method under ActiveModel::Dirty.

Two auxiliary methods are supplied:

model.tracked.set_all_changed
model.tracked.set_all_unchanged

Which sets all tracked attributes to changed/unchaged states.

Concrete Example

Assume you have a User model which has the following attributes: name, address, current_job

class User < ActiveRecord::Base
end

And you want to keep track on all those users who changed their current jobs or addresses:

rails generate track_it User address current_job

And

rake db:migrate

Let's take a look at the effects of our change:

u = User.create!(:name => "user1", :adderss => "address1", :current_job => "job1")

u.address = "address2"
u.current_job = "job2"

u.current_job_changed? # => true
u.address_changed? # => true
u.changed? # => true
u.changed # => ['address', 'current_job']

u.tracked.current_job_changed? # => false
u.tracked.address_changed? # => false
u.tracked.changed? # => false
u.tracked.changed # => []

u.save!

u.current_job_changed? # => false
u.address_changed? # => false
u.changed? # => false
u.changed # => []


u.tracked.current_job_changed? # => true
u.tracked.address_changed? # => true
u.tracked.changed? # => true
u.tracked.changed # => ['address', 'current_job']

u.tracked.set_unchanged(:current_job)
u.tracked.current_job_changed? # => false

u.tracked.set_changed(:current_job)
u.tracked.current_job_changed? # => true

u.tracked.set_all_unchanged
u.tracked.changed? # => false
u.tracked.changed # => []

u.tracked.set_all_changed
u.tracked.changed? # => true
u.tracked.changed # => ['address', 'current_job'] # note name is not changed - only tracked attributes get changed.