From 93734629a33591486b76e3b9884ea37650934eef Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Fri, 30 May 2014 13:06:05 -0700 Subject: [PATCH] Don't change values in `@raw_attributes` during serialization During `init_with`, the attributes given to the coder will be placed into `@raw_attributes`. As such, we should read from `@raw_attributes` when encoding, rather than `@attributes`, which has been type cast. --- .../lib/active_record/attribute_methods.rb | 2 +- .../attribute_methods/serialization.rb | 2 +- activerecord/test/cases/store_test.rb | 14 -------------- .../test/cases/yaml_serialization_test.rb | 19 ++++++++++++------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index fb6473b7c7..d2a8006069 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -289,7 +289,7 @@ module ActiveRecord # Placeholder so it can be overriden when needed by serialization def attributes_for_coder # :nodoc: - attributes + attributes_before_type_cast end # Returns an #inspect-like string for the value of the diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index b247bf8a45..e8a52719ef 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -138,7 +138,7 @@ module ActiveRecord attrs[name] = if self.class.serialized_attributes.include?(name) @raw_attributes[name].serialized_value else - read_attribute(name) + read_attribute_before_type_cast(name) end end end diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index 6a34c55011..f841b1c983 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -183,20 +183,6 @@ class StoreTest < ActiveRecord::TestCase assert_equal({}, @john.params) end - test "attributes_for_coder should return stored fields already serialized" do - attributes = { - "id" => @john.id, - "name"=> @john.name, - "settings" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ncolor: black\n", - "preferences" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nremember_login: true\n", - "json_data" => "{\"height\":\"tall\"}", "json_data_empty"=>"{\"is_a_good_guy\":true}", - "params" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess {}\n", - "account_id"=> @john.account_id - } - - assert_equal attributes, @john.attributes_for_coder - end - test "dump, load and dump again a model" do dumped = YAML.dump(@john) loaded = YAML.load(dumped) diff --git a/activerecord/test/cases/yaml_serialization_test.rb b/activerecord/test/cases/yaml_serialization_test.rb index 15815d56e4..f7af9a35cd 100644 --- a/activerecord/test/cases/yaml_serialization_test.rb +++ b/activerecord/test/cases/yaml_serialization_test.rb @@ -23,13 +23,6 @@ class YamlSerializationTest < ActiveRecord::TestCase assert_equal({:omg=>:lol}, YAML.load(YAML.dump(topic)).content) end - def test_encode_with_coder - topic = Topic.first - coder = {} - topic.encode_with coder - assert_equal({'attributes' => topic.attributes}, coder) - end - def test_psych_roundtrip topic = Topic.first assert topic @@ -47,4 +40,16 @@ class YamlSerializationTest < ActiveRecord::TestCase def test_active_record_relation_serialization [Topic.all].to_yaml end + + def test_raw_types_are_not_changed_on_round_trip + topic = Topic.new(parent_id: "123") + assert_equal "123", topic.parent_id_before_type_cast + assert_equal "123", YAML.load(YAML.dump(topic)).parent_id_before_type_cast + end + + def test_cast_types_are_not_changed_on_round_trip + topic = Topic.new(parent_id: "123") + assert_equal 123, topic.parent_id + assert_equal 123, YAML.load(YAML.dump(topic)).parent_id + end end