Question

I don't think there is an easy way to apply PaperTrail to all model except by declaring has_paper_trail in each one. What I want to accomplish is to leverage the features of PaperTrail (or another gem, like Auditable, Vestal Versions) to all the models. For example, I want to include models generated by gems and engines (Rails 3).

Any pointers on how to apply a "global" PaperTrail (or similar gem)?

Was it helpful?

Solution

For Rails 5.0+ (if app has the ApplicationRecord class)

class ApplicationRecord < ActiveRecord::Base
  def self.inherited subclass
    super
    subclass.send(:has_paper_trail)
  end
end

For older Rails versions

# config/initializers/paper_trail_extension.rb 
ActiveRecord::Base.singleton_class.prepend Module.new {
  def inherited subclass
    super
    skipped_models = ["ActiveRecord::SchemaMigration", "PaperTrail::Version", "ActiveRecord::SessionStore::Session"]
    unless skipped_models.include?(subclass.to_s)
      subclass.send(:has_paper_trail)
    end
  end
}

(It is important that you use {/} and not do/end after Module.new because of operator precedence).

OTHER TIPS

You could extend the ActiveRecord::Base module with a monkeypatch:

# config/initializers/active_record_paper_trail.rb
class ActiveRecord::Base
  has_paper_trail
end

Might do the job, depends if it can include the gem at that point... try it and see

You can just inherit all your models from a MyModel class (similar to using an ApplicationController)...

class Posts < MyModel
end

class Comments < MyModel
end

class MyModel < ActiveRecord::Base
     self.abstract_class = true

     has_paper_trail
end

Don't forget the self.abstract_class = true in the base model.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top