diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-11-18 15:19:15 -0800 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-11-18 15:20:19 -0800 |
commit | 08576b94ad4f19dfc368619d7751e211d23dcad8 (patch) | |
tree | a8be0f668e65f0c90a79cd3031984c507225019c /activerecord/lib/active_record/attribute_methods | |
parent | 78e7a0d3b7eaafe1ad0a45e3e355e1123cae3f8b (diff) | |
download | rails-08576b94ad4f19dfc368619d7751e211d23dcad8.tar.gz rails-08576b94ad4f19dfc368619d7751e211d23dcad8.tar.bz2 rails-08576b94ad4f19dfc368619d7751e211d23dcad8.zip |
Improve the performance of reading attributes
We added a comparison to "id", and call to `self.class.primary_key` a
*lot*. We also have performance hits from `&block` all over the place.
We skip the check in a new method, in order to avoid breaking the
behavior of `read_attribute`
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods')
3 files changed, 12 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index 2f02738f6d..9ba46ec4c7 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -110,7 +110,7 @@ module ActiveRecord if attribute_changed?(attr) changed_attributes[attr] else - clone_attribute_value(:read_attribute, attr) + clone_attribute_value(:_read_attribute, attr) end end diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index 104d84a1f8..c28374e4ab 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -17,7 +17,7 @@ module ActiveRecord def id if pk = self.class.primary_key sync_with_transaction_state - read_attribute(pk) + _read_attribute(pk) end end diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 55beb309ca..20f0936e52 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -27,7 +27,7 @@ module ActiveRecord <<-EOMETHOD def #{method_name} name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{const_name} - read_attribute(name) { |n| missing_attribute(n, caller) } + _read_attribute(name) { |n| missing_attribute(n, caller) } end EOMETHOD end @@ -64,7 +64,7 @@ module ActiveRecord generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 def #{temp_method} name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name} - read_attribute(name) { |n| missing_attribute(n, caller) } + _read_attribute(name) { |n| missing_attribute(n, caller) } end STR @@ -84,13 +84,19 @@ module ActiveRecord def read_attribute(attr_name, &block) name = attr_name.to_s name = self.class.primary_key if name == ID - @attributes.fetch_value(name, &block) + _read_attribute(name, &block) + end + + # This method exists to avoid the expensive primary_key check internally, without + # breaking compatibility with the read_attribute API + def _read_attribute(attr_name) # :nodoc: + @attributes.fetch_value(attr_name.to_s) { |n| yield n if block_given? } end private def attribute(attribute_name) - read_attribute(attribute_name) + _read_attribute(attribute_name) end end end |