Skip to content

Commit

Permalink
Backport fix for #512 and #525; (Properly handles virtual attributes …
Browse files Browse the repository at this point in the history
…with custom setters in VersionConcern#reify)
  • Loading branch information
batter committed Apr 29, 2015
1 parent 5f4e36e commit a2a1c1c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/paper_trail/version_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ def reify(options = {})

# Set all the attributes in this version on the model
attrs.each do |k, v|
if model.respond_to?("#{k}=")
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
Expand Down
20 changes: 20 additions & 0 deletions test/dummy/app/models/song.rb
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -9,4 +10,23 @@ def length=(minutes)
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
15 changes: 15 additions & 0 deletions test/unit/model_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,21 @@ def without(&block)
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 = nil
end

should 'return persist the changes on the live instance properly' do
assert_equal nil, @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


Expand Down

0 comments on commit a2a1c1c

Please sign in to comment.