From a6cf6ec98b58dc2a7d0586ccb6ef970d93f0bafc Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 1 Feb 2011 11:07:02 -0800 Subject: move the coders to the serialized_attributes hash --- activerecord/lib/active_record/attribute_methods/read.rb | 10 +++------- activerecord/lib/active_record/base.rb | 12 ++++-------- activerecord/lib/active_record/coders/yaml_column.rb | 7 ++++++- activerecord/lib/active_record/validations/uniqueness.rb | 6 ++++-- 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) -- cgit v1.2.3