Share This Article
PaperTrail is a Ruby Gem that allows you to keep track of changes made to your models and store them as versions.
You can revert back to older versions if you need to, which can be really handy.
Installing PaperTrail is pretty simple, you just need to add it to your Gemfile.
gem 'paper_trail', '~> 10.0'
Using PaperTrail in Rails
If you are using Rails, there’s an additional step you need to take. You need to generate a migration that will add the columns that PaperTrail needs to your database.
rails generate paper_trail:install
Once you’ve done that, you can go ahead and add the paper_trail concern to your model.
class Widget < ActiveRecord::Base
has_paper_trail
end
Working with Versions
Once you’ve setup PaperTrail, you can start working with the versions of your models.
Let’s say you have a Widget model and you’ve made some changes to it, you can access those changes like this:
widget = Widget.last
versions = widget.versions
puts versions.map(&:event)
# ["create", "update"]
You can also revert back to an older version by using the revert_to
method.
widget.revert_to(versions.last)
You can also get a specific version by using the version_at
method.
widget.version_at(versions.last.created_at)
If you make a change and then save the model, a new version will be created.
You can access the newer version by using the current_version
method.
widget.update(name: "foo")
widget.current_version.reify
PaperTrail Callbacks
PaperTrail also provides some callbacks that you can use in your models.
The paper_trail_enabled_for_model
callback allows you to control whether PaperTrail should be used for a specific model.
The paper_trail_enabled_for_request
, on the other hand, allows you to control whether PaperTrail should be used for a specific request.
You can use these callbacks to disable PaperTrail in your tests, for example.
Here’s an example:
class Widget < ActiveRecord::Base
has_paper_trail
def self.paper_trail_enabled_for_model
!Rails.env.test?
end
end
PaperTrail with non-ActiveRecord Models
PaperTrail also works with non-ActiveRecord models, you just need to include the PaperTrail::Model
module.
Here’s an example:
class Widget
include PaperTrail::Model
def self.paper_trail_enabled_for_model
!Rails.env.test?
end
end
Ignoring Model Changes
If you want to ignore changes to specific attributes, you can use the paper_trail_options
method.
Here’s an example:
class Widget < ActiveRecord::Base
has_paper_trail
def self.paper_trail_options
{
on: [:create, :update],
except: [:updated_at, :created_at],
}
end
end
You can also specify a version_alias
, which is the name you want to use for the version.
Here’s an example:
class Widget < ActiveRecord::Base
has_paper_trail
def self.paper_trail_options
{
on: [:create, :update],
except: [:updated_at, :created_at],
version_alias: :paper_trail_version,
}
end
end
If you want to disable PaperTrail for a specific model, you can set the paper_trail_enabled_for_model
to false.
Here’s an example:
class Widget < ActiveRecord::Base
has_paper_trail
def self.paper_trail_enabled_for_model
false
end
end
PaperTrail with Other Rails Versions
PaperTrail also works with other versions of Rails, such as Rails 3.
The steps are pretty much the same, but there’s a small difference in the way you add the concern to your models.
Here’s an example:
class Widget < ActiveRecord::Base
include PaperTrail::Concerns::Widget
end
You can also use the paper_trail
method
For a full list of configuration options, see the PaperTrail documentation.
That’s it for this article. Now you know how to use PaperTrail to track changes to your data.