aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods/serialization.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods/serialization.rb')
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb59
1 files changed, 37 insertions, 22 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index d1eb3d5bfc..165785c8fb 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -6,10 +6,24 @@ module ActiveRecord
included do
# Returns a hash of all the attributes that have been specified for serialization as
# keys and their class restriction as values.
- class_attribute :serialized_attributes
+ config_attribute :serialized_attributes
self.serialized_attributes = {}
end
+ class Type # :nodoc:
+ def initialize(column)
+ @column = column
+ end
+
+ def type_cast(value)
+ value.unserialized_value
+ end
+
+ def type
+ @column.type
+ end
+ end
+
class Attribute < Struct.new(:coder, :value, :state)
def unserialized_value
state == :serialized ? unserialize : value
@@ -58,39 +72,40 @@ module ActiveRecord
self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder)
end
- def define_method_attribute(attr_name)
- if serialized_attributes.include?(attr_name)
- generated_attribute_methods.module_eval(<<-CODE, __FILE__, __LINE__)
- def _#{attr_name}
- @attributes['#{attr_name}'].unserialized_value
- end
- alias #{attr_name} _#{attr_name}
- CODE
- else
- super
+ def initialize_attributes(attributes) #:nodoc:
+ super
+
+ serialized_attributes.each do |key, coder|
+ if attributes.key?(key)
+ attributes[key] = Attribute.new(coder, attributes[key], :serialized)
+ end
end
+
+ attributes
end
- end
- def set_serialized_attributes
- self.class.serialized_attributes.each do |key, coder|
- if @attributes.key?(key)
- @attributes[key] = Attribute.new(coder, @attributes[key], :serialized)
+ private
+
+ def attribute_cast_code(attr_name)
+ if serialized_attributes.include?(attr_name)
+ "v.unserialized_value"
+ else
+ super
end
end
end
- def type_cast_attribute(column, value)
- if column && self.class.serialized_attributes[column.name]
- value.unserialized_value
+ 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 type_cast_attribute_for_write(column, value)
- if column && coder = self.class.serialized_attributes[column.name]
- Attribute.new(coder, value, :unserialized)
+ def read_attribute_before_type_cast(attr_name)
+ if serialized_attributes.include?(attr_name)
+ super.unserialized_value
else
super
end