mirror of
https://github.com/paper-trail-gem/paper_trail.git
synced 2022-11-09 11:33:19 -05:00
When building the :object_changes metadata, use the serialized value for any attributes that are serialized
This commit is contained in:
parent
28171e15d2
commit
8b8579a81a
4 changed files with 65 additions and 4 deletions
|
@ -175,15 +175,29 @@ module PaperTrail
|
||||||
:whodunnit => PaperTrail.whodunnit
|
:whodunnit => PaperTrail.whodunnit
|
||||||
}
|
}
|
||||||
if version_class.column_names.include? 'object_changes'
|
if version_class.column_names.include? 'object_changes'
|
||||||
# The double negative (reject, !include?) preserves the hash structure of self.changes.
|
data[:object_changes] = changes_for_paper_trail.to_yaml
|
||||||
data[:object_changes] = self.changes.reject do |key, value|
|
|
||||||
!notably_changed.include?(key)
|
|
||||||
end.to_yaml
|
|
||||||
end
|
end
|
||||||
send(self.class.versions_association_name).build merge_metadata(data)
|
send(self.class.versions_association_name).build merge_metadata(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def changes_for_paper_trail
|
||||||
|
# The double negative (reject, !include?) preserves the hash structure of self.changes.
|
||||||
|
self.changes.reject do |key, value|
|
||||||
|
!notably_changed.include?(key)
|
||||||
|
end.tap do |changes_hash|
|
||||||
|
# Use serialized value for attributes that are serialized
|
||||||
|
changes_hash.each do |key, (old_value, new_value)|
|
||||||
|
if serialized_attributes.include?(key)
|
||||||
|
# serializer.dump(new_value) is the same as @attributes[key].serialized_value
|
||||||
|
serializer = @attributes[key].coder
|
||||||
|
changes_hash[key] = [serializer.dump(old_value),
|
||||||
|
serializer.dump(new_value)]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def record_destroy
|
def record_destroy
|
||||||
if switched_on? and not new_record?
|
if switched_on? and not new_record?
|
||||||
version_class.create merge_metadata(:item_id => self.id,
|
version_class.create merge_metadata(:item_id => self.id,
|
||||||
|
|
|
@ -2,4 +2,27 @@ class Person < ActiveRecord::Base
|
||||||
has_many :authorships, :dependent => :destroy
|
has_many :authorships, :dependent => :destroy
|
||||||
has_many :books, :through => :authorships
|
has_many :books, :through => :authorships
|
||||||
has_paper_trail
|
has_paper_trail
|
||||||
|
|
||||||
|
# Convert strings to TimeZone objects when assigned
|
||||||
|
def time_zone=(value)
|
||||||
|
if value.is_a? ActiveSupport::TimeZone
|
||||||
|
super
|
||||||
|
else
|
||||||
|
zone = ::Time.find_zone(value) # nil if can't find time zone
|
||||||
|
super zone
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Store TimeZone objects as strings when serialized to database
|
||||||
|
class TimeZoneSerializer
|
||||||
|
def dump(zone)
|
||||||
|
zone.try(:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load(value)
|
||||||
|
::Time.find_zone!(value) rescue nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
serialize :time_zone, TimeZoneSerializer.new
|
||||||
end
|
end
|
||||||
|
|
|
@ -80,6 +80,7 @@ class SetUpTestTables < ActiveRecord::Migration
|
||||||
|
|
||||||
create_table :people, :force => true do |t|
|
create_table :people, :force => true do |t|
|
||||||
t.string :name
|
t.string :name
|
||||||
|
t.string "time_zone"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table :songs, :force => true do |t|
|
create_table :songs, :force => true do |t|
|
||||||
|
|
|
@ -906,6 +906,29 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'When an attribute has a custom serializer' do
|
||||||
|
setup { @person = Person.create(:time_zone => "UTC") }
|
||||||
|
|
||||||
|
should "be an instance of ActiveSupport::TimeZone" do
|
||||||
|
assert_equal ActiveSupport::TimeZone, @person.time_zone.class
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when that attribute is updated' do
|
||||||
|
setup { @person.update_attributes({ :time_zone => 'Pacific Time (US & Canada)' }) }
|
||||||
|
|
||||||
|
should 'have used the value returned by the serializer' do
|
||||||
|
assert_equal ['UTC', 'Pacific Time (US & Canada)'], @person.versions.last.changeset[:time_zone]
|
||||||
|
assert_equal @person.instance_variable_get(:@attributes)['time_zone'].serialized_value, @person.versions.last.changeset[:time_zone].last
|
||||||
|
end
|
||||||
|
|
||||||
|
should 'not have stored the default, ridiculously long (to_yaml) serialization of the time_zone object' do
|
||||||
|
# Before the serialized attributes fix, the object_changes that was stored was ridiculously long (58723)
|
||||||
|
assert @person.versions.last.object_changes.length < 105, "object_changes length was #{@person.versions.last.object_changes.length}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
context 'A new model instance which uses a custom Version class' do
|
context 'A new model instance which uses a custom Version class' do
|
||||||
setup { @post = Post.new }
|
setup { @post = Post.new }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue