From ee161d1bc01a761abf5473d5a8d53f8684be93e9 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 25 Jan 2012 17:30:29 -0800 Subject: [PATCH] moved most of the evald code in to regular ruby code --- .../active_record/attribute_methods/read.rb | 38 ++++++++++++++----- .../attribute_methods/serialization.rb | 4 +- .../attribute_methods/time_zone_conversion.rb | 7 +--- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 73e473391a913..6d36e6a004730 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -92,17 +92,13 @@ def cacheable_column?(column) end def internal_attribute_access_code(attr_name, cast_code) - cast_code = instance_cast_code(attr_name) - - access_code = "v = @attributes.fetch(attr_name) { missing_attribute(attr_name, caller) };" - - access_code << "v && #{cast_code};" + method = instance_cast_method(attr_name) if cache_attribute?(attr_name) - access_code = "@attributes_cache[attr_name] ||= (#{access_code})" + "cached_cast_attribute('#{attr_name}', :#{method})" + else + "cast_attribute('#{attr_name}', :#{method})" end - - "attr_name = '#{attr_name}'; #{access_code}" end def external_attribute_access_code(attr_name, cast_code) @@ -119,8 +115,8 @@ def attribute_cast_code(attr_name) columns_hash[attr_name].type_cast_code('v') end - def instance_cast_code(attr_name) - "@columns_hash[attr_name].type_cast(v)" + def instance_cast_method(attr_name) + "cast_column" end end @@ -132,6 +128,28 @@ def read_attribute(attr_name) private + def cached_cast_attribute(attr_name, method) + @attributes_cache[attr_name] ||= cast_attribute(attr_name, method) + end + + def cast_attribute(attr_name, method) + v = @attributes.fetch(attr_name) { missing_attribute(attr_name, caller) } + v && send(method, attr_name, v) + end + + def cast_serialized(attr_name, value) + value.unserialized_value + end + + def cast_tz_conversion(attr_name, value) + value = cast_column(attr_name, value) + value.acts_like?(:time) ? value.in_time_zone : value + end + + def cast_column(attr_name, value) + @columns_hash[attr_name].type_cast value + end + def attribute(attribute_name) read_attribute(attribute_name) end diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index fbace73f7a39d..38e7bf77ef5f8 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -80,9 +80,9 @@ def attribute_cast_code(attr_name) end end - def instance_cast_code(attr_name) + def instance_cast_method(attr_name) if serialized_attributes.include?(attr_name) - "v.unserialized_value" + "cast_serialized" else super end diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb index 30ee0947b3606..19dcceea88f55 100644 --- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb +++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -53,14 +53,11 @@ def #{attr_name}=(original_time) end private - def instance_cast_code(attr_name) + def instance_cast_method(attr_name) column = columns_hash[attr_name] if create_time_zone_conversion_attribute?(attr_name, column) - typecast = "v = #{super}" - time_zone_conversion = "v.acts_like?(:time) ? v.in_time_zone : v" - - "((#{typecast}) && (#{time_zone_conversion}))" + "cast_tz_conversion" else super end