aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-11-30 15:52:09 +0000
committerJon Leighton <j@jonathanleighton.com>2011-11-30 23:18:40 +0000
commitf4853dc17490c88966721ca1ad422baf6ae49745 (patch)
treee59c90b90a5078fce41c34d3cd4c3ba87ab0353e /activerecord
parent61489dc6844539c86558f00670802c71927f9b51 (diff)
downloadrails-f4853dc17490c88966721ca1ad422baf6ae49745.tar.gz
rails-f4853dc17490c88966721ca1ad422baf6ae49745.tar.bz2
rails-f4853dc17490c88966721ca1ad422baf6ae49745.zip
Extract attribute serialization code into a separate module
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record.rb1
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb33
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb42
-rw-r--r--activerecord/lib/active_record/base.rb1
4 files changed, 49 insertions, 28 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index 3572c640eb..bf28cffbbe 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -92,6 +92,7 @@ module ActiveRecord
autoload :Read
autoload :TimeZoneConversion
autoload :Write
+ autoload :Serialization
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 78dbbeb0e6..d3ef7f0ae5 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -34,22 +34,12 @@ module ActiveRecord
protected
def define_method_attribute(attr_name)
- if serialized_attributes.include?(attr_name)
- define_read_method_for_serialized_attribute(attr_name)
- else
- define_read_method(attr_name, attr_name, columns_hash[attr_name])
- end
+ define_read_method(attr_name, attr_name, columns_hash[attr_name])
end
private
def cacheable_column?(column)
- serialized_attributes.include?(column.name) || attribute_types_cached_by_default.include?(column.type)
- end
-
- # Define read method for serialized attribute.
- def define_read_method_for_serialized_attribute(attr_name)
- access_code = "@attributes_cache['#{attr_name}'] ||= @attributes['#{attr_name}']"
- generated_attribute_methods.module_eval("def _#{attr_name}; #{access_code}; end; alias #{attr_name} _#{attr_name}", __FILE__, __LINE__)
+ attribute_types_cached_by_default.include?(column.type)
end
# Define an attribute reader method. Cope with nil column.
@@ -107,28 +97,15 @@ module ActiveRecord
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
- if unserializable_attribute?(attr_name, column)
- unserialize_attribute(attr_name)
- else
- column.type_cast(value)
- end
+ type_cast_attribute(column, value)
else
value
end
end
end
- # Returns true if the attribute is of a text column and marked for serialization.
- def unserializable_attribute?(attr_name, column)
- column.text? && self.class.serialized_attributes.include?(attr_name)
- end
-
- # Returns the unserialized object of the attribute.
- def unserialize_attribute(attr_name)
- coder = self.class.serialized_attributes[attr_name]
- unserialized_object = coder.load(@attributes[attr_name])
-
- @attributes.frozen? ? unserialized_object : @attributes[attr_name] = unserialized_object
+ def type_cast_attribute(column, value) #:nodoc:
+ column.type_cast(value)
end
private
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
new file mode 100644
index 0000000000..686754fbc2
--- /dev/null
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -0,0 +1,42 @@
+module ActiveRecord
+ module AttributeMethods
+ module Serialization
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ def define_method_attribute(attr_name)
+ if serialized_attributes.include?(attr_name)
+ generated_attribute_methods.module_eval(<<-CODE, __FILE__, __LINE__)
+ def _#{attr_name}
+ @attributes_cache['#{attr_name}'] ||= @attributes['#{attr_name}']
+ end
+ alias #{attr_name} _#{attr_name}
+ CODE
+ else
+ super
+ end
+ end
+
+ def cacheable_column?(column)
+ serialized_attributes.include?(column.name) || super
+ end
+ end
+
+ def type_cast_attribute(column, value)
+ coder = self.class.serialized_attributes[column.name]
+
+ if column.text? && coder
+ unserialized_object = coder.load(@attributes[column.name])
+
+ if @attributes.frozen?
+ unserialized_object
+ else
+ @attributes[column.name] = unserialized_object
+ end
+ else
+ super
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 2a02380591..f8f10d651f 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -2219,6 +2219,7 @@ MSG
include AttributeMethods::PrimaryKey
include AttributeMethods::TimeZoneConversion
include AttributeMethods::Dirty
+ include AttributeMethods::Serialization
include ActiveModel::MassAssignmentSecurity
include Callbacks, ActiveModel::Observing, Timestamp
include Associations, NamedScope