Global enable/disable for PaperTrail.

Thanks to these commits from jeremyw:

* 9254147
* 3748fd3..66463e6
This commit is contained in:
Andy Stewart 2010-03-19 15:21:07 +00:00
parent a981969e9a
commit 4f4f814500
5 changed files with 96 additions and 8 deletions

View File

@ -14,7 +14,8 @@ PaperTrail lets you track changes to your models' data. It's good for auditing
* Automatically records who was responsible if your controller has a `current_user` method. * Automatically records who was responsible if your controller has a `current_user` method.
* Allows you to set who is responsible at model-level (useful for migrations). * Allows you to set who is responsible at model-level (useful for migrations).
* Allows you to store arbitrary metadata with each version (useful for filtering versions). * Allows you to store arbitrary metadata with each version (useful for filtering versions).
* Can be turned off/on (useful for migrations). * Can be turned off/on per class (useful for migrations).
* Can be turned off/on globally (useful for testing).
* No configuration necessary. * No configuration necessary.
* Stores everything in a single database table (generates migration for you). * Stores everything in a single database table (generates migration for you).
* Thoroughly tested. * Thoroughly tested.
@ -171,11 +172,9 @@ Why would you do this? In this example, `author_id` is an attribute of `Article
## Turning PaperTrail Off/On ## Turning PaperTrail Off/On
Sometimes you don't want to store changes. Perhaps you are only interested in changes made Sometimes you don't want to store changes. Perhaps you are only interested in changes made by your users and don't need to store changes you make yourself in, say, a migration -- or when testing your application.
by your users and don't need to store changes you make yourself in, say, a migration.
If you are about change some widgets and you don't want a paper trail of your changes, you can If you are about change some widgets and you don't want a paper trail of your changes, you can turn PaperTrail off like this:
turn PaperTrail off like this:
>> Widget.paper_trail_off >> Widget.paper_trail_off
@ -183,6 +182,38 @@ And on again like this:
>> Widget.paper_trail_on >> Widget.paper_trail_on
You can also disable PaperTrail for all models:
>> PaperTrail.enabled = false
For example, you might want to disable PaperTrail in your Rails application's test environment to speed up your tests. This will do it:
# in config/environments/test.rb
config.after_initialize do
PaperTrail.enabled = false
end
If you disable PaperTrail in your test environment but want to enable it for specific tests, you can add a helper like this to your test helper:
# in test/test_helper.rb
def with_versioning
was_enabled = PaperTrail.enabled?
PaperTrail.enabled = true
begin
yield
ensure
PaperTrail.enabled = was_enabled
end
end
And then use it in your tests like this:
test "something that needs versioning" do
with_versioning do
# your test
end
end
## Installation ## Installation

View File

@ -1,4 +1,5 @@
require 'yaml' require 'yaml'
require 'paper_trail/config'
require 'paper_trail/has_paper_trail' require 'paper_trail/has_paper_trail'
require 'paper_trail/version' require 'paper_trail/version'
@ -8,6 +9,23 @@ module PaperTrail
base.before_filter :set_whodunnit base.before_filter :set_whodunnit
end end
# Returns PaperTrail's configuration object.
def self.config
@@config ||= PaperTrail::Config.instance
end
# Switches PaperTrail on or off.
def self.enabled=(value)
PaperTrail.config.enabled = value
end
# Returns `true` if PaperTrail is on, `false` otherwise.
# PaperTrail is enabled by default.
def self.enabled?
!!PaperTrail.config.enabled
end
# Returns who is reponsible for any changes that occur.
def self.whodunnit def self.whodunnit
Thread.current[:whodunnit] Thread.current[:whodunnit]
end end

11
lib/paper_trail/config.rb Normal file
View File

@ -0,0 +1,11 @@
module PaperTrail
class Config
include Singleton
attr_accessor :enabled
def initialize
# Indicates whether PaperTrail is on or off.
@enabled = true
end
end
end

View File

@ -20,6 +20,8 @@ module PaperTrail
cattr_accessor :meta cattr_accessor :meta
self.meta = options[:meta] || {} self.meta = options[:meta] || {}
# Indicates whether or not PaperTrail is active for this class.
# This is independent of whether PaperTrail is globally enabled or disabled.
cattr_accessor :paper_trail_active cattr_accessor :paper_trail_active
self.paper_trail_active = true self.paper_trail_active = true
@ -30,10 +32,12 @@ module PaperTrail
after_destroy :record_destroy after_destroy :record_destroy
end end
# Switches PaperTrail off for this class.
def paper_trail_off def paper_trail_off
self.paper_trail_active = false self.paper_trail_active = false
end end
# Switches PaperTrail on for this class.
def paper_trail_on def paper_trail_on
self.paper_trail_active = true self.paper_trail_active = true
end end
@ -42,13 +46,13 @@ module PaperTrail
module InstanceMethods module InstanceMethods
def record_create def record_create
if self.class.paper_trail_active if switched_on?
versions.create merge_metadata(:event => 'create', :whodunnit => PaperTrail.whodunnit) versions.create merge_metadata(:event => 'create', :whodunnit => PaperTrail.whodunnit)
end end
end end
def record_update def record_update
if changed_and_we_care? and self.class.paper_trail_active if switched_on? && changed_and_we_care?
versions.build merge_metadata(:event => 'update', versions.build merge_metadata(:event => 'update',
:object => object_to_string(previous_version), :object => object_to_string(previous_version),
:whodunnit => PaperTrail.whodunnit) :whodunnit => PaperTrail.whodunnit)
@ -56,7 +60,7 @@ module PaperTrail
end end
def record_destroy def record_destroy
if self.class.paper_trail_active if switched_on?
versions.create merge_metadata(:event => 'destroy', versions.create merge_metadata(:event => 'destroy',
:object => object_to_string(previous_version), :object => object_to_string(previous_version),
:whodunnit => PaperTrail.whodunnit) :whodunnit => PaperTrail.whodunnit)
@ -100,6 +104,12 @@ module PaperTrail
def changed_and_we_care? def changed_and_we_care?
changed? and !(changed - self.class.ignore).empty? changed? and !(changed - self.class.ignore).empty?
end end
# Returns `true` if PaperTrail is globally enabled and active for this class,
# `false` otherwise.
def switched_on?
PaperTrail.enabled? && self.class.paper_trail_active
end
end end
end end

View File

@ -260,6 +260,23 @@ class HasPaperTrailModelTest < Test::Unit::TestCase
context 'A record' do context 'A record' do
setup { @widget = Widget.create :name => 'Zaphod' } setup { @widget = Widget.create :name => 'Zaphod' }
context 'with PaperTrail globally disabled' do
setup do
PaperTrail.enabled = false
@count = @widget.versions.length
end
teardown { PaperTrail.enabled = true }
context 'when updated' do
setup { @widget.update_attributes :name => 'Beeblebrox' }
should 'not add to its trail' do
assert_equal @count, @widget.versions.length
end
end
end
context 'with its paper trail turned off' do context 'with its paper trail turned off' do
setup do setup do
Widget.paper_trail_off Widget.paper_trail_off
@ -483,4 +500,5 @@ class HasPaperTrailModelTest < Test::Unit::TestCase
end end
end end
end end