diff --git a/CHANGELOG.md b/CHANGELOG.md index 074c3b4b..40eca831 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ ## 2.7.2 (Unreleased) - - [#187](https://github.com/airblade/paper_trail/pull/187) - Confirmed JRuby support. - [#219](https://github.com/airblade/paper_trail/pull/219) - Fixed issue where attributes stored with `nil` value might not get reified properly depending on the way the serializer worked. + - [#187](https://github.com/airblade/paper_trail/pull/187) - Confirmed JRuby support. + - [#174](https://github.com/airblade/paper_trail/pull/174) - The `event` field on the versions table can now be customized. ## 2.7.1 diff --git a/README.md b/README.md index 35fe148c..f5aaeefb 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,23 @@ class Article < ActiveRecord::Base end ``` +You may also have the `Version` model save a custom string in it's `event` field instead of the typical `create`, `update`, `destroy`. +PaperTrail supplies a custom accessor method called `paper_trail_event`, which it will attempt to use to fill the `event` field before +falling back on one of the default events. + +```ruby +>> a = Article.create +>> a.versions.size # 1 +>> a.versions.last.event # 'create' +>> a.paper_trail_event = 'update title' +>> a.update_attributes :title => 'My Title' +>> a.versions.size # 2 +>> a.versions.last.event # 'update title' +>> a.paper_trail_event = nil +>> a.update_attributes :title => "Alternate" +>> a.versions.size # 3 +>> a.versions.last.event # 'update' +``` ## Choosing When To Save New Versions diff --git a/lib/paper_trail/has_paper_trail.rb b/lib/paper_trail/has_paper_trail.rb index b6940edf..3201736f 100644 --- a/lib/paper_trail/has_paper_trail.rb +++ b/lib/paper_trail/has_paper_trail.rb @@ -57,6 +57,8 @@ module PaperTrail class_attribute :versions_association_name self.versions_association_name = options[:versions] || :versions + attr_accessor :paper_trail_event + has_many self.versions_association_name, :class_name => version_class_name, :as => :item, @@ -190,7 +192,7 @@ module PaperTrail def record_create if switched_on? data = { - :event => 'create', + :event => paper_trail_event || 'create', :whodunnit => PaperTrail.whodunnit } @@ -205,7 +207,7 @@ module PaperTrail def record_update if switched_on? && changed_notably? data = { - :event => 'update', + :event => paper_trail_event || 'update', :object => object_to_string(item_before_change), :whodunnit => PaperTrail.whodunnit } @@ -228,7 +230,7 @@ module PaperTrail if switched_on? and not new_record? version_class.create merge_metadata(:item_id => self.id, :item_type => self.class.base_class.name, - :event => 'destroy', + :event => paper_trail_event || 'destroy', :object => object_to_string(item_before_change), :whodunnit => PaperTrail.whodunnit) end diff --git a/test/unit/model_test.rb b/test/unit/model_test.rb index 0bc58070..dc5506fa 100644 --- a/test/unit/model_test.rb +++ b/test/unit/model_test.rb @@ -1212,6 +1212,60 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase end end + context 'custom events' do + context 'on create' do + setup do + Fluxor.reset_callbacks :create + Fluxor.reset_callbacks :update + Fluxor.reset_callbacks :destroy + Fluxor.instance_eval <<-END + has_paper_trail :on => [:create] + END + @fluxor = Fluxor.new.tap { |model| model.paper_trail_event = 'created' } + @fluxor.update_attributes :name => 'blah' + @fluxor.destroy + end + should 'only have a version for the created event' do + assert_equal 1, @fluxor.versions.length + assert_equal 'created', @fluxor.versions.last.event + end + end + context 'on update' do + setup do + Fluxor.reset_callbacks :create + Fluxor.reset_callbacks :update + Fluxor.reset_callbacks :destroy + Fluxor.instance_eval <<-END + has_paper_trail :on => [:update] + END + @fluxor = Fluxor.create.tap { |model| model.paper_trail_event = 'name_updated' } + @fluxor.update_attributes :name => 'blah' + @fluxor.destroy + end + should 'only have a version for the name_updated event' do + assert_equal 1, @fluxor.versions.length + assert_equal 'name_updated', @fluxor.versions.last.event + end + end + context 'on destroy' do + setup do + Fluxor.reset_callbacks :create + Fluxor.reset_callbacks :update + Fluxor.reset_callbacks :destroy + Fluxor.instance_eval <<-END + has_paper_trail :on => [:destroy] + END + @fluxor = Fluxor.create.tap { |model| model.paper_trail_event = 'destroyed' } + @fluxor.update_attributes :name => 'blah' + @fluxor.destroy + end + should 'only have a version for the destroy event' do + assert_equal 1, @fluxor.versions.length + assert_equal 'destroyed', @fluxor.versions.last.event + end + end + end + private # Updates `model`'s last version so it looks like the version was