aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-11-30 16:00:19 +0000
committerJon Leighton <j@jonathanleighton.com>2011-11-30 23:18:40 +0000
commit6c63f1aa44780c887dd3e52765e86588911c2802 (patch)
treebfba65146d6abbdca1eb4acabfe532dc7aaeafc9 /activerecord/lib/active_record/attribute_methods
parentf4853dc17490c88966721ca1ad422baf6ae49745 (diff)
downloadrails-6c63f1aa44780c887dd3e52765e86588911c2802.tar.gz
rails-6c63f1aa44780c887dd3e52765e86588911c2802.tar.bz2
rails-6c63f1aa44780c887dd3e52765e86588911c2802.zip
Move some serialization stuff out of Base
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods')
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb42
1 files changed, 42 insertions, 0 deletions
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]