提交 351331fb 编写于 作者: G Guillermo Álvarez 提交者: Aaron Patterson

Make serialized columns with explicit object_type return a new instance of the...

Make serialized columns with explicit object_type return a new instance of the object instead of nil
上级 080345ba
......@@ -249,6 +249,17 @@ module ActiveRecord #:nodoc:
# user = User.create(:preferences => %w( one two three ))
# User.find(user.id).preferences # raises SerializationTypeMismatch
#
# When you specify a class option, the default value for that attribute will be a new
# instance of that class.
#
# class User < ActiveRecord::Base
# serialize :preferences, OpenStruct
# end
#
# user = User.new
# user.preferences.theme_color = "red"
#
#
# == Single table inheritance
#
# Active Record allows inheritance by storing the name of the class in a column that by
......@@ -1409,6 +1420,7 @@ def initialize(attributes = nil)
@changed_attributes = {}
ensure_proper_type
set_serialized_attributes
populate_with_current_scope_attributes
self.attributes = attributes unless attributes.nil?
......@@ -1447,10 +1459,7 @@ def encode_with(coder)
def init_with(coder)
@attributes = coder['attributes']
(@attributes.keys & self.class.serialized_attributes.keys).each do |key|
coder = self.class.serialized_attributes[key]
@attributes[key] = coder.load @attributes[key]
end
set_serialized_attributes
@attributes_cache, @previously_changed, @changed_attributes = {}, {}, {}
@association_cache = {}
......@@ -1461,6 +1470,13 @@ def init_with(coder)
run_callbacks :initialize
end
def set_serialized_attributes
(@attributes.keys & self.class.serialized_attributes.keys).each do |key|
coder = self.class.serialized_attributes[key]
@attributes[key] = coder.load @attributes[key]
end
end
# Specifies how the record is dumped by +Marshal+.
#
# +_dump+ emits a marshalled hash which has been passed to +encode_with+. Override this
......
......@@ -19,6 +19,7 @@ def dump(obj)
end
def load(yaml)
return object_class.new if object_class != Object && yaml.nil?
return yaml unless yaml.is_a?(String) && yaml =~ /^---/
begin
obj = YAML.load(yaml)
......@@ -27,6 +28,7 @@ def load(yaml)
raise SerializationTypeMismatch,
"Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
end
obj ||= object_class.new if object_class != Object
obj
rescue *RESCUE_ERRORS
......
......@@ -1002,6 +1002,25 @@ def test_serialized_attribute_with_class_constraint
Topic.serialize(:content)
end
def test_serialized_default_class
Topic.serialize(:content, Hash)
topic = Topic.new
assert_equal Hash, topic.content.class
assert_equal Hash, topic.read_attribute(:content).class
topic.content["beer"] = "MadridRb"
assert topic.save
topic.reload
assert_equal Hash, topic.content.class
assert_equal "MadridRb", topic.content["beer"]
ensure
Topic.serialize(:content)
end
def test_serialized_no_default_class_for_object
topic = Topic.new
assert_nil topic.content
end
def test_serialized_boolean_value_true
Topic.serialize(:content)
topic = Topic.new(:content => true)
......
require "cases/helper"
module ActiveRecord
......@@ -20,9 +21,9 @@ def test_nil_is_ok
assert_nil coder.load "--- "
end
def test_nil_is_ok_with_different_class
def test_returns_new_with_different_class
coder = YAMLColumn.new SerializationTypeMismatch
assert_nil coder.load "--- "
assert_equal SerializationTypeMismatch, coder.load("--- ").class
end
def test_returns_string_unless_starts_with_dash
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册