Skip excess cloning of JSONized `object_changes` (#1189)
* Skip excess cloning of JSONized `object_changes` * Suggestions for PR 1189, to be squashed
This commit is contained in:
parent
ccf5e1e4d5
commit
ca4f532623
|
@ -238,9 +238,14 @@ module PaperTrail
|
||||||
# serialization here, using `PaperTrail.serializer`.
|
# serialization here, using `PaperTrail.serializer`.
|
||||||
#
|
#
|
||||||
# @api private
|
# @api private
|
||||||
|
# @param changes HashWithIndifferentAccess
|
||||||
def recordable_object_changes(changes)
|
def recordable_object_changes(changes)
|
||||||
if PaperTrail.config.object_changes_adapter&.respond_to?(:diff)
|
if PaperTrail.config.object_changes_adapter&.respond_to?(:diff)
|
||||||
changes = PaperTrail.config.object_changes_adapter.diff(changes)
|
# We'd like to avoid the `to_hash` here, because it increases memory
|
||||||
|
# usage, but that would be a breaking change because
|
||||||
|
# `object_changes_adapter` expects a plain `Hash`, not a
|
||||||
|
# `HashWithIndifferentAccess`.
|
||||||
|
changes = PaperTrail.config.object_changes_adapter.diff(changes.to_hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
if @record.class.paper_trail.version_class.object_changes_col_is_json?
|
if @record.class.paper_trail.version_class.object_changes_col_is_json?
|
||||||
|
@ -285,7 +290,10 @@ module PaperTrail
|
||||||
AttributeSerializers::ObjectChangesAttribute.
|
AttributeSerializers::ObjectChangesAttribute.
|
||||||
new(@record.class).
|
new(@record.class).
|
||||||
serialize(changes)
|
serialize(changes)
|
||||||
changes.to_hash
|
|
||||||
|
# We'd like to convert this `HashWithIndifferentAccess` to a plain
|
||||||
|
# `Hash`, but we don't, to save memory.
|
||||||
|
changes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,12 @@ module PaperTrail
|
||||||
::YAML.load string
|
::YAML.load string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @param object (Hash | HashWithIndifferentAccess) - Coming from
|
||||||
|
# `recordable_object` `object` will be a plain `Hash`. However, due to
|
||||||
|
# recent [memory optimizations](https://git.io/fjeYv), when coming from
|
||||||
|
# `recordable_object_changes`, it will be a `HashWithIndifferentAccess`.
|
||||||
def dump(object)
|
def dump(object)
|
||||||
|
object = object.to_hash if object.is_a?(HashWithIndifferentAccess)
|
||||||
::YAML.dump object
|
::YAML.dump object
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ module PaperTrail
|
||||||
float: 4.2
|
float: 4.2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let(:hash_with_indifferent_access) { HashWithIndifferentAccess.new(hash) }
|
||||||
|
|
||||||
describe ".load" do
|
describe ".load" do
|
||||||
it "deserializes YAML to Ruby" do
|
it "deserializes YAML to Ruby" do
|
||||||
|
@ -26,6 +27,8 @@ module PaperTrail
|
||||||
describe ".dump" do
|
describe ".dump" do
|
||||||
it "serializes Ruby to YAML" do
|
it "serializes Ruby to YAML" do
|
||||||
expect(described_class.dump(hash)).to eq(hash.to_yaml)
|
expect(described_class.dump(hash)).to eq(hash.to_yaml)
|
||||||
|
expect(described_class.dump(hash_with_indifferent_access)).
|
||||||
|
to eq(hash.stringify_keys.to_yaml)
|
||||||
expect(described_class.dump(array)).to eq(array.to_yaml)
|
expect(described_class.dump(array)).to eq(array.to_yaml)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue