mirror of https://github.com/rails/rails
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.
This commit is contained in:
parent
afc124c3b4
commit
4e7217027f
|
@ -7,13 +7,29 @@ module ActiveRecord
|
||||||
when 1 then coder
|
when 1 then coder
|
||||||
else
|
else
|
||||||
if coder["attributes"].is_a?(AttributeSet)
|
if coder["attributes"].is_a?(AttributeSet)
|
||||||
coder
|
Rails420.convert(klass, coder)
|
||||||
else
|
else
|
||||||
Rails41.convert(klass, coder)
|
Rails41.convert(klass, coder)
|
||||||
end
|
end
|
||||||
end
|
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
|
module Rails41
|
||||||
def self.convert(klass, coder)
|
def self.convert(klass, coder)
|
||||||
attributes = klass.attributes_builder
|
attributes = klass.attributes_builder
|
||||||
|
|
|
@ -92,31 +92,7 @@ class YamlSerializationTest < ActiveRecord::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_deserializing_rails_41_yaml
|
def test_deserializing_rails_41_yaml
|
||||||
yaml = <<-YAML.strip_heredoc
|
topic = YAML.load(yaml_fixture("rails_4_1"))
|
||||||
--- !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)
|
|
||||||
|
|
||||||
assert topic.new_record?
|
assert topic.new_record?
|
||||||
assert_equal nil, topic.id
|
assert_equal nil, topic.id
|
||||||
|
@ -124,6 +100,22 @@ class YamlSerializationTest < ActiveRecord::TestCase
|
||||||
assert_equal({ omg: :lol }, topic.content)
|
assert_equal({ omg: :lol }, topic.content)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue