aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-12-22 19:11:11 +0000
committerJon Leighton <j@jonathanleighton.com>2011-12-22 19:23:26 +0000
commitc1d3e66858cee041df16a2338a5c75a637b30148 (patch)
tree22a792e186d303276e2eabad31c47ca08efa858d /activerecord/lib/active_record/attribute_methods
parent367741ef22d1538b8550cf6e4b2276a0946066c0 (diff)
downloadrails-c1d3e66858cee041df16a2338a5c75a637b30148.tar.gz
rails-c1d3e66858cee041df16a2338a5c75a637b30148.tar.bz2
rails-c1d3e66858cee041df16a2338a5c75a637b30148.zip
Make read_attribute code path accessible at the class level
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods')
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb40
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb20
2 files changed, 33 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 77bf9d0905..a83d944d1b 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -39,6 +39,26 @@ module ActiveRecord
super
end
+ def type_cast_attribute(attr_name, attributes, cache = {}) #:nodoc:
+ return unless attr_name
+ attr_name = attr_name.to_s
+
+ if generated_external_attribute_methods.method_defined?(attr_name)
+ if attributes.has_key?(attr_name) || attr_name == 'id'
+ generated_external_attribute_methods.send(attr_name, attributes[attr_name], attributes, cache, attr_name)
+ end
+ elsif !attribute_methods_generated?
+ # If we haven't generated the caster methods yet, do that and
+ # then try again
+ define_attribute_methods
+ type_cast_attribute(attr_name, attributes, cache)
+ else
+ # If we get here, the attribute has no associated DB column, so
+ # just return it verbatim.
+ attributes[attr_name]
+ end
+ end
+
protected
# We want to generate the methods via module_eval rather than define_method,
# because define_method is slower on dispatch and uses more memory (because it
@@ -105,25 +125,7 @@ module ActiveRecord
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
def read_attribute(attr_name)
- return unless attr_name
-
- attr_name = attr_name.to_s
- methods = self.class.generated_external_attribute_methods
-
- if methods.method_defined?(attr_name)
- if @attributes.has_key?(attr_name) || attr_name == 'id'
- methods.send(attr_name, @attributes[attr_name], @attributes, @attributes_cache, attr_name)
- end
- elsif !self.class.attribute_methods_generated?
- # If we haven't generated the caster methods yet, do that and
- # then try again
- self.class.define_attribute_methods
- read_attribute(attr_name)
- else
- # If we get here, the attribute has no associated DB column, so
- # just return it verbatim.
- @attributes[attr_name]
- end
+ self.class.type_cast_attribute(attr_name, @attributes, @attributes_cache)
end
private
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 0a4432506f..2ffd91f796 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -58,6 +58,18 @@ module ActiveRecord
self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder)
end
+ 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
+
private
def attribute_cast_code(attr_name)
@@ -69,14 +81,6 @@ module ActiveRecord
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)
- end
- end
- end
-
def type_cast_attribute_for_write(column, value)
if column && coder = self.class.serialized_attributes[column.name]
Attribute.new(coder, value, :unserialized)