diff options
author | Sean Griffin <sean@thoughtbot.com> | 2015-03-10 11:54:17 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2015-03-10 11:56:45 -0600 |
commit | 4e7217027f1933d5860ba459b3d23f454272f709 (patch) | |
tree | af7c4945c79c3abf42099d4bcec012b01280dc6f /activerecord | |
parent | afc124c3b417b5327ed4d85dc34393f3d19bfbcf (diff) | |
download | rails-4e7217027f1933d5860ba459b3d23f454272f709.tar.gz rails-4e7217027f1933d5860ba459b3d23f454272f709.tar.bz2 rails-4e7217027f1933d5860ba459b3d23f454272f709.zip |
Add YAML compatibility for objects from Rails 4.2
As of Ruby 2.2, Psych can handle any object which is marshallable. This
was not true on previous versions of Ruby, so our delegator types had to
provide their own implementation of `init_with` and `encode_with`.
Unfortunately, this doesn't match up with what Psych will do today.
Since by the time we hit this layer, the objects will have already been
created, I think it makes the most sense to just grab the current type
from the class.
Diffstat (limited to 'activerecord')
4 files changed, 239 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/legacy_yaml_adapter.rb b/activerecord/lib/active_record/legacy_yaml_adapter.rb index 0d018d4352..89dee58423 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 65cd54e380..56909a8630 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 0000000000..20b128db9c --- /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 0000000000..b3d3b33141 --- /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 |