From 4f4f814500450382257551282a9fd84e7fe1b5ae Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Fri, 19 Mar 2010 15:21:07 +0000 Subject: [PATCH] Global enable/disable for PaperTrail. Thanks to these commits from jeremyw: * 9254147 * 3748fd3..66463e6 --- README.md | 41 ++++++++++++++++++++++++++---- lib/paper_trail.rb | 18 +++++++++++++ lib/paper_trail/config.rb | 11 ++++++++ lib/paper_trail/has_paper_trail.rb | 16 +++++++++--- test/paper_trail_model_test.rb | 18 +++++++++++++ 5 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 lib/paper_trail/config.rb diff --git a/README.md b/README.md index 2e378051..f0492348 100644 --- a/README.md +++ b/README.md @@ -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. * 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). -* 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. * Stores everything in a single database table (generates migration for you). * 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 -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. +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. -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: +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: >> Widget.paper_trail_off @@ -183,6 +182,38 @@ And on again like this: >> 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 diff --git a/lib/paper_trail.rb b/lib/paper_trail.rb index 7b01f441..ed670b00 100644 --- a/lib/paper_trail.rb +++ b/lib/paper_trail.rb @@ -1,4 +1,5 @@ require 'yaml' +require 'paper_trail/config' require 'paper_trail/has_paper_trail' require 'paper_trail/version' @@ -8,6 +9,23 @@ module PaperTrail base.before_filter :set_whodunnit 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 Thread.current[:whodunnit] end diff --git a/lib/paper_trail/config.rb b/lib/paper_trail/config.rb new file mode 100644 index 00000000..55ef1083 --- /dev/null +++ b/lib/paper_trail/config.rb @@ -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 diff --git a/lib/paper_trail/has_paper_trail.rb b/lib/paper_trail/has_paper_trail.rb index 3016db93..6a171fd3 100644 --- a/lib/paper_trail/has_paper_trail.rb +++ b/lib/paper_trail/has_paper_trail.rb @@ -20,6 +20,8 @@ module PaperTrail cattr_accessor :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 self.paper_trail_active = true @@ -30,10 +32,12 @@ module PaperTrail after_destroy :record_destroy end + # Switches PaperTrail off for this class. def paper_trail_off self.paper_trail_active = false end + # Switches PaperTrail on for this class. def paper_trail_on self.paper_trail_active = true end @@ -42,13 +46,13 @@ module PaperTrail module InstanceMethods def record_create - if self.class.paper_trail_active + if switched_on? versions.create merge_metadata(:event => 'create', :whodunnit => PaperTrail.whodunnit) end end 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', :object => object_to_string(previous_version), :whodunnit => PaperTrail.whodunnit) @@ -56,7 +60,7 @@ module PaperTrail end def record_destroy - if self.class.paper_trail_active + if switched_on? versions.create merge_metadata(:event => 'destroy', :object => object_to_string(previous_version), :whodunnit => PaperTrail.whodunnit) @@ -100,6 +104,12 @@ module PaperTrail def changed_and_we_care? changed? and !(changed - self.class.ignore).empty? 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 diff --git a/test/paper_trail_model_test.rb b/test/paper_trail_model_test.rb index 9befde0f..f21ceca3 100644 --- a/test/paper_trail_model_test.rb +++ b/test/paper_trail_model_test.rb @@ -260,6 +260,23 @@ class HasPaperTrailModelTest < Test::Unit::TestCase context 'A record' do 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 setup do Widget.paper_trail_off @@ -483,4 +500,5 @@ class HasPaperTrailModelTest < Test::Unit::TestCase end end + end