From 6c63f1aa44780c887dd3e52765e86588911c2802 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Wed, 30 Nov 2011 16:00:19 +0000 Subject: Move some serialization stuff out of Base --- .../attribute_methods/serialization.rb | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'activerecord/lib/active_record/attribute_methods') diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index 686754fbc2..001620d889 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -3,7 +3,41 @@ module ActiveRecord module Serialization extend ActiveSupport::Concern + 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 + self.serialized_attributes = {} + end + module ClassMethods + # If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object, + # then specify the name of that attribute using this method and it will be handled automatically. + # The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that + # class on retrieval or SerializationTypeMismatch will be raised. + # + # ==== Parameters + # + # * +attr_name+ - The field name that should be serialized. + # * +class_name+ - Optional, class name that the object type should be equal to. + # + # ==== Example + # # Serialize a preferences attribute + # class User < ActiveRecord::Base + # serialize :preferences + # end + def serialize(attr_name, class_name = Object) + coder = if [:load, :dump].all? { |x| class_name.respond_to?(x) } + class_name + else + Coders::YAMLColumn.new(class_name) + end + + # 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 + def define_method_attribute(attr_name) if serialized_attributes.include?(attr_name) generated_attribute_methods.module_eval(<<-CODE, __FILE__, __LINE__) @@ -22,6 +56,14 @@ module ActiveRecord end end + def set_serialized_attributes + sattrs = self.class.serialized_attributes + + sattrs.each do |key, coder| + @attributes[key] = coder.load @attributes[key] if @attributes.key?(key) + end + end + def type_cast_attribute(column, value) coder = self.class.serialized_attributes[column.name] -- cgit v1.2.3