diff --git a/lib/paper_trail/version_concern.rb b/lib/paper_trail/version_concern.rb index 32a1292c..9efa9001 100644 --- a/lib/paper_trail/version_concern.rb +++ b/lib/paper_trail/version_concern.rb @@ -186,6 +186,8 @@ module PaperTrail attrs.each do |k, v| if model.has_attribute?(k) model[k.to_sym] = v + elsif model.respond_to?("#{k}=") + model.send("#{k}=", v) else logger.warn "Attribute #{k} does not exist on #{item_type} (Version id: #{id})." end diff --git a/test/dummy/app/models/song.rb b/test/dummy/app/models/song.rb index 7c5ee23d..cef53a07 100644 --- a/test/dummy/app/models/song.rb +++ b/test/dummy/app/models/song.rb @@ -1,6 +1,7 @@ # Example from 'Overwriting default accessors' in ActiveRecord::Base. class Song < ActiveRecord::Base has_paper_trail + attr_accessor :name # Uses an integer of seconds to hold the length of the song def length=(minutes) @@ -9,4 +10,23 @@ class Song < ActiveRecord::Base def length read_attribute(:length) / 60 end + + # override attributes hashes like some libraries do + def attributes_with_name + if name + attributes_without_name.merge(:name => name) + else + attributes_without_name + end + end + alias_method_chain :attributes, :name + + def changed_attributes_with_name + if name + changed_attributes_without_name.merge(:name => name) + else + changed_attributes_without_name + end + end + alias_method_chain :changed_attributes, :name end diff --git a/test/unit/model_test.rb b/test/unit/model_test.rb index f8d29ccd..af5bf6cd 100644 --- a/test/unit/model_test.rb +++ b/test/unit/model_test.rb @@ -1126,6 +1126,21 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase should 'return "overwritten" value on reified instance' do assert_equal 4, @song.versions.last.reify.length end + + context 'Has a virtual attribute injected into the ActiveModel::Dirty changes' do + setup do + @song.name = 'Good Vibrations' + @song.save + @song.name = 'Yellow Submarine' + end + + should 'return persist the changes on the live instance properly' do + assert_equal 'Yellow Submarine', @song.name + end + should 'return "overwritten" virtual attribute on the reified instance' do + assert_equal 'Good Vibrations', @song.versions.last.reify.name + end + end end