diff options
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods/serialization.rb')
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/serialization.rb | 61 |
1 files changed, 9 insertions, 52 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index c3466153d6..b247bf8a45 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -58,53 +58,18 @@ module ActiveRecord Coders::YAMLColumn.new(class_name_or_coder) end + type = columns_hash[attr_name.to_s].cast_type + if type.serialized? + type = type.subtype + end + property attr_name, Type::Serialized.new(type, coder) + # merge new serialized attribute and create new hash to ensure that each class in inheritance hierarchy # has its own hash of own serialized attributes self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder) end end - class Type # :nodoc: - def initialize(column) - @column = column - end - - def type_cast(value) - if value.state == :serialized - value.unserialized_value @column.type_cast value.value - else - value.unserialized_value - end - end - - def type - @column.type - end - - def accessor - ActiveRecord::Store::IndifferentHashAccessor - end - end - - class Attribute < Struct.new(:coder, :value, :state) # :nodoc: - def unserialized_value(v = value) - state == :serialized ? unserialize(v) : value - end - - def serialized_value - state == :unserialized ? serialize : value - end - - def unserialize(v) - self.state = :unserialized - self.value = coder.load(v) - end - - def serialize - self.state = :serialized - self.value = coder.dump(value) - end - end # This is only added to the model when serialize is called, which # ensures we do not make things slower when serialization is not used. @@ -118,7 +83,7 @@ module ActiveRecord serialized_attributes.each do |key, coder| if attributes.key?(key) - attributes[key] = Attribute.new(coder, attributes[key], serialized) + attributes[key] = Type::Serialized::Attribute.new(coder, attributes[key], serialized) end end @@ -134,14 +99,6 @@ module ActiveRecord super | (attributes.keys & self.class.serialized_attributes.keys) end - def type_cast_attribute_for_write(column, value) - if column && coder = self.class.serialized_attributes[column.name] - Attribute.new(coder, value, :unserialized) - else - super - end - end - def _field_changed?(attr, old, value) if self.class.serialized_attributes.include?(attr) old != value @@ -170,7 +127,7 @@ module ActiveRecord def typecasted_attribute_value(name) if self.class.serialized_attributes.include?(name) - @attributes[name].serialized_value + @raw_attributes[name].serialized_value else super end @@ -179,7 +136,7 @@ module ActiveRecord def attributes_for_coder attribute_names.each_with_object({}) do |name, attrs| attrs[name] = if self.class.serialized_attributes.include?(name) - @attributes[name].serialized_value + @raw_attributes[name].serialized_value else read_attribute(name) end |