diff --git a/activerecord/lib/active_record/legacy_yaml_adapter.rb b/activerecord/lib/active_record/legacy_yaml_adapter.rb index 0d018d4352b..89dee584236 100644 --- a/activerecord/lib/active_record/legacy_yaml_adapter.rb +++ b/activerecord/lib/active_record/legacy_yaml_adapter.rb @@ -7,13 +7,29 @@ module ActiveRecord when 1 then coder else if coder["attributes"].is_a?(AttributeSet) - coder + Rails420.convert(klass, coder) else Rails41.convert(klass, coder) end end end + module Rails420 + def self.convert(klass, coder) + attribute_set = coder["attributes"] + + klass.attribute_names.each do |attr_name| + attribute = attribute_set[attr_name] + if attribute.type.is_a?(Delegator) + type_from_klass = klass.type_for_attribute(attr_name) + attribute_set[attr_name] = attribute.with_type(type_from_klass) + end + end + + coder + end + end + module Rails41 def self.convert(klass, coder) attributes = klass.attributes_builder diff --git a/activerecord/test/cases/yaml_serialization_test.rb b/activerecord/test/cases/yaml_serialization_test.rb index 65cd54e3807..56909a86302 100644 --- a/activerecord/test/cases/yaml_serialization_test.rb +++ b/activerecord/test/cases/yaml_serialization_test.rb @@ -92,31 +92,7 @@ class YamlSerializationTest < ActiveRecord::TestCase end def test_deserializing_rails_41_yaml - yaml = <<-YAML.strip_heredoc - --- !ruby/object:Topic - attributes: - id: - title: The First Topic - author_name: David - author_email_address: david@loudthinking.com - written_on: 2003-07-16 14:28:11.223300000 Z - bonus_time: 2000-01-01 14:28:00.000000000 Z - last_read: 2004-04-15 - content: | - --- - :omg: :lol - important: - approved: false - replies_count: 1 - unique_replies_count: 0 - parent_id: - parent_title: - type: - group: - created_at: 2015-03-10 17:05:42.000000000 Z - updated_at: 2015-03-10 17:05:42.000000000 Z - YAML - topic = YAML.load(yaml) + topic = YAML.load(yaml_fixture("rails_4_1")) assert topic.new_record? assert_equal nil, topic.id @@ -124,6 +100,22 @@ class YamlSerializationTest < ActiveRecord::TestCase assert_equal({ omg: :lol }, topic.content) end - def test_deserializing_rails_42_yaml + def test_deserializing_rails_4_2_0_yaml + topic = YAML.load(yaml_fixture("rails_4_2_0")) + + assert_not topic.new_record? + assert_equal 1, topic.id + assert_equal "The First Topic", topic.title + assert_equal("Have a nice day", topic.content) + end + + private + + def yaml_fixture(file_name) + path = File.expand_path( + "../../support/yaml_compatibility_fixtures/#{file_name}.yml", + __FILE__ + ) + File.read(path) end end diff --git a/activerecord/test/support/yaml_compatibility_fixtures/rails_4_1.yml b/activerecord/test/support/yaml_compatibility_fixtures/rails_4_1.yml new file mode 100644 index 00000000000..20b128db9ca --- /dev/null +++ b/activerecord/test/support/yaml_compatibility_fixtures/rails_4_1.yml @@ -0,0 +1,22 @@ +--- !ruby/object:Topic + attributes: + id: + title: The First Topic + author_name: David + author_email_address: david@loudthinking.com + written_on: 2003-07-16 14:28:11.223300000 Z + bonus_time: 2000-01-01 14:28:00.000000000 Z + last_read: 2004-04-15 + content: | + --- + :omg: :lol + important: + approved: false + replies_count: 1 + unique_replies_count: 0 + parent_id: + parent_title: + type: + group: + created_at: 2015-03-10 17:05:42.000000000 Z + updated_at: 2015-03-10 17:05:42.000000000 Z diff --git a/activerecord/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml b/activerecord/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml new file mode 100644 index 00000000000..b3d3b331414 --- /dev/null +++ b/activerecord/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml @@ -0,0 +1,182 @@ +--- !ruby/object:Topic +raw_attributes: + id: 1 + title: The First Topic + author_name: David + author_email_address: david@loudthinking.com + written_on: '2003-07-16 14:28:11.223300' + bonus_time: '2005-01-30 14:28:00.000000' + last_read: '2004-04-15' + content: | + --- Have a nice day + ... + important: + approved: f + replies_count: 1 + unique_replies_count: 0 + parent_id: + parent_title: + type: + group: + created_at: '2015-03-10 17:44:41' + updated_at: '2015-03-10 17:44:41' +attributes: !ruby/object:ActiveRecord::AttributeSet + attributes: !ruby/object:ActiveRecord::LazyAttributeHash + types: + id: &5 !ruby/object:ActiveRecord::Type::Integer + precision: + scale: + limit: + range: !ruby/range + begin: -2147483648 + end: 2147483648 + excl: true + title: &6 !ruby/object:ActiveRecord::Type::String + precision: + scale: + limit: 250 + author_name: &1 !ruby/object:ActiveRecord::Type::String + precision: + scale: + limit: + author_email_address: *1 + written_on: &4 !ruby/object:ActiveRecord::Type::DateTime + precision: + scale: + limit: + bonus_time: &7 !ruby/object:ActiveRecord::Type::Time + precision: + scale: + limit: + last_read: &8 !ruby/object:ActiveRecord::Type::Date + precision: + scale: + limit: + content: !ruby/object:ActiveRecord::Type::Serialized + coder: &9 !ruby/object:ActiveRecord::Coders::YAMLColumn + object_class: !ruby/class 'Object' + subtype: &2 !ruby/object:ActiveRecord::Type::Text + precision: + scale: + limit: + important: *2 + approved: &10 !ruby/object:ActiveRecord::Type::Boolean + precision: + scale: + limit: + replies_count: &3 !ruby/object:ActiveRecord::Type::Integer + precision: + scale: + limit: + range: !ruby/range + begin: -2147483648 + end: 2147483648 + excl: true + unique_replies_count: *3 + parent_id: *3 + parent_title: *1 + type: *1 + group: *1 + created_at: *4 + updated_at: *4 + values: + id: 1 + title: The First Topic + author_name: David + author_email_address: david@loudthinking.com + written_on: '2003-07-16 14:28:11.223300' + bonus_time: '2005-01-30 14:28:00.000000' + last_read: '2004-04-15' + content: | + --- Have a nice day + ... + important: + approved: f + replies_count: 1 + unique_replies_count: 0 + parent_id: + parent_title: + type: + group: + created_at: '2015-03-10 17:44:41' + updated_at: '2015-03-10 17:44:41' + additional_types: {} + materialized: true + delegate_hash: + id: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: id + value_before_type_cast: 1 + type: *5 + title: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: title + value_before_type_cast: The First Topic + type: *6 + author_name: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: author_name + value_before_type_cast: David + type: *1 + author_email_address: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: author_email_address + value_before_type_cast: david@loudthinking.com + type: *1 + written_on: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: written_on + value_before_type_cast: '2003-07-16 14:28:11.223300' + type: *4 + bonus_time: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: bonus_time + value_before_type_cast: '2005-01-30 14:28:00.000000' + type: *7 + last_read: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: last_read + value_before_type_cast: '2004-04-15' + type: *8 + content: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: content + value_before_type_cast: | + --- Have a nice day + ... + type: !ruby/object:ActiveRecord::Type::Serialized + coder: *9 + subtype: *2 + important: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: important + value_before_type_cast: + type: *2 + approved: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: approved + value_before_type_cast: f + type: *10 + replies_count: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: replies_count + value_before_type_cast: 1 + type: *3 + unique_replies_count: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: unique_replies_count + value_before_type_cast: 0 + type: *3 + parent_id: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: parent_id + value_before_type_cast: + type: *3 + parent_title: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: parent_title + value_before_type_cast: + type: *1 + type: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: type + value_before_type_cast: + type: *1 + group: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: group + value_before_type_cast: + type: *1 + created_at: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: created_at + value_before_type_cast: '2015-03-10 17:44:41' + type: *4 + updated_at: !ruby/object:ActiveRecord::Attribute::FromDatabase + name: updated_at + value_before_type_cast: '2015-03-10 17:44:41' + type: *4 +new_record: false