aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb10
-rw-r--r--activerecord/lib/active_record/base.rb12
-rw-r--r--activerecord/lib/active_record/coders/yaml_column.rb7
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb6
4 files changed, 17 insertions, 18 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index ff088200a1..895c16b9b3 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -106,14 +106,10 @@ module ActiveRecord
# Returns the unserialized object of the attribute.
def unserialize_attribute(attr_name)
- unserialized_object = object_from_yaml(@attributes[attr_name])
+ coder = self.class.serialized_attributes[attr_name]
+ unserialized_object = coder.load(@attributes[attr_name])
- if unserialized_object.is_a?(self.class.serialized_attributes[attr_name]) || unserialized_object.nil?
- @attributes.frozen? ? unserialized_object : @attributes[attr_name] = unserialized_object
- else
- raise SerializationTypeMismatch,
- "#{attr_name} was supposed to be a #{self.class.serialized_attributes[attr_name]}, but was a #{unserialized_object.class.to_s}"
- end
+ @attributes.frozen? ? unserialized_object : @attributes[attr_name] = unserialized_object
end
private
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 1e762a287d..42226f83ea 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -536,7 +536,7 @@ module ActiveRecord #:nodoc:
# serialize :preferences
# end
def serialize(attr_name, class_name = Object)
- serialized_attributes[attr_name.to_s] = class_name
+ serialized_attributes[attr_name.to_s] = Coders::YAMLColumn.new(class_name)
end
# Guesses the table name (in forced lower-case) based on the name of the class in the
@@ -1738,8 +1738,9 @@ MSG
if include_readonly_attributes || (!include_readonly_attributes && !self.class.readonly_attributes.include?(name))
value = read_attribute(name)
- if !value.nil? && self.class.serialized_attributes.key?(name)
- value = YAML.dump value
+ coder = self.class.serialized_attributes[name]
+ if !value.nil? && coder
+ value = coder.dump value
end
attrs[self.class.arel_table[name]] = value
end
@@ -1865,11 +1866,6 @@ MSG
end
end
- def object_from_yaml(string)
- return string unless string.is_a?(String) && string =~ /^---/
- YAML::load(string) rescue string
- end
-
def populate_with_current_scope_attributes
if scope = self.class.send(:current_scoped_methods)
create_with = scope.scope_for_create
diff --git a/activerecord/lib/active_record/coders/yaml_column.rb b/activerecord/lib/active_record/coders/yaml_column.rb
index 9b0df119ef..fcecc11aba 100644
--- a/activerecord/lib/active_record/coders/yaml_column.rb
+++ b/activerecord/lib/active_record/coders/yaml_column.rb
@@ -14,16 +14,21 @@ module ActiveRecord
@object_class = object_class
end
+ def dump(obj)
+ YAML.dump obj
+ end
+
def load(yaml)
return yaml unless yaml.is_a?(String) && yaml =~ /^---/
begin
- obj = YAML::load(yaml)
+ obj = YAML.load(yaml)
unless obj.is_a?(object_class) || obj.nil?
raise SerializationTypeMismatch,
"Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
end
+ obj
rescue *RESCUE_ERRORS
yaml
end
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index e6a2b40403..a96796f9ff 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -15,8 +15,10 @@ module ActiveRecord
def validate_each(record, attribute, value)
finder_class = find_finder_class_for(record)
- if value && record.class.serialized_attributes.key?(attribute.to_s)
- value = YAML.dump value
+ coder = record.class.serialized_attributes[attribute.to_s]
+
+ if value && coder
+ value = coder.dump value
end
sql, params = mount_sql_and_params(finder_class, record.class.quoted_table_name, attribute, value)