PaperTrail-Actor
This gem is an extension for PaperTrail that allows you to set an ActiveRecord object as the "whodunnit" field. This enhancement provides more granular tracking of who made changes, making it easier to trace modifications in your application.
Features
- Set an ActiveRecord Object for Whodunnit: Use an
ActiveRecordobject to track who made changes. - Return the ActiveRecord Object: The method
#actorcan be used to get the object responsible for changes. - Coexistence with Existing Versions: Works seamlessly alongside existing PaperTrail versions, regardless of when they were created.
How it works
This gem works by storing the globalid to the whodunnit field of PaperTrail version tables. This allows you to add different object types to the whodunnit field, know exactly which object is responsible, and retrive that object with ease.
For example, if you have both Admin objects and User objects that are capable of making changes, this gem ensures that you can clearly identify who made the change instead of using purely an ID and not knowing if it was for an Admin or a User
Installation
- Add
paper_trail-actorto your Gemfile:ruby gem "paper_trail-actor" - Run the following command:
sh bundle install
Usage
Basic Setup
To use this gem, you first need to set a user (or any ActiveRecord object) to the whodunnit field.
product = Product.find(42)
admin = Admin.find(1)
PaperTrail.request.whodunnit = admin
PaperTrail.request.whodunnit # "gid://app/Admin/1"
PaperTrail.request.actor # Returns the `Admin` object with id 1
When you update the product, PaperTrail will remember who made the change:
product.update(name: "Ice cream")
product.versions.last.whodunnit # "gid://app/Admin/1"
product.versions.last.actor # Returns the `Admin` object with id 1
Flexible Whodunnit
The gem is designed to be flexible. You can set whodunnit with various types of objects:
Strings:
PaperTrail.request.whodunnit = "Alex the admin" # "Alex the admin"New/unpersisted ActiveRecord Objects:
PaperTrail.request.whodunnit = Admin.new # Sets the string representation of the adminNon-ActiveRecord Objects:
class Job def to_s "A job in the system" end end
PaperTrail.request.whodunnit = Job.new # "A job in the system"
When you update the product, PaperTrail will store the string for who made the change:
```ruby
product.update(name: "Ice cream")
product.versions.last.whodunnit # "A job in the system"
product.versions.last.actor # "A job in the system"
Updating Existing Versions
If you have existing PaperTrail versions and need to update them, you can do so by:
first_product_version = product.versions.first
admin_id = first_product_version.actor # For example, "1"
admin = Admin.find_by(id: admin_id)
if admin.present?
first_product_version.whodunnit = admin
first_product_version.save
end
Setting whodunnit with a controller callback
You can set the user for PaperTrail in the same way that the PaperTrail documentation states.
However, setting this to an ActiveRecord object now records the globalid. It also allows the object to be retrived from created PaperTrail versions with the #actor method.
If your controller has a #current_user method, PaperTrail-Actor will assign the globalid of the current user to whodunnit. If your controller doesn't have a #current_user, or if the current user is nil, then whodunnit will not be set.
You may want set #user_for_paper_trail to call a different method to find out who is responsible. To do so, override the #user_for_paper_trail method in your controller:
class ApplicationController < ActionController::Base
before_action :set_paper_trail_whodunnit
def user_for_paper_trail
logged_in? ? current_admin : "Public user"
end
end
Contributing
- Please add tests for PRs that are created.
- Run the tests
bundle exec rake specto ensure that they all pass. - Lint the code
bundle exec rake standard:fixto ensure that convention is maintained.