aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-06-12 09:00:03 -0600
committerSean Griffin <sean@thoughtbot.com>2014-06-12 17:23:23 -0600
commitd82dafe65c1137a2f84975c202d471054533f7bc (patch)
treead493c4ce897d58a97b79276221d42d7837e1e18 /activerecord
parent46139d33c06715e74ad450428ece3ee84da98579 (diff)
downloadrails-d82dafe65c1137a2f84975c202d471054533f7bc.tar.gz
rails-d82dafe65c1137a2f84975c202d471054533f7bc.tar.bz2
rails-d82dafe65c1137a2f84975c202d471054533f7bc.zip
Fix performance regression on preloading HABTM associations
We'd spend a lot of time calling `hash` and `eql?` on the join model, which has no primary key. Calling `id` with no primary key is a really slow way to get back `nil`, so we can improve the performance there. However, even with the escape clause, we *still* weren't getting high enough performance, as we were checking the primary key too much. `hash` will always return `nil.hash` for records with no id, and `==` will always return `false`. We can optimize those cases in the HABTM join model.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb1
-rw-r--r--activerecord/lib/active_record/core.rb2
2 files changed, 2 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 931209b07b..cb550b0683 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -15,6 +15,7 @@ module ActiveRecord
# Returns the primary key value.
def id
+ return unless self.class.primary_key
sync_with_transaction_state
read_attribute(self.class.primary_key)
end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 7edaf256c7..6d1897ab40 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -380,7 +380,7 @@ module ActiveRecord
# Delegates to id in order to allow two records of the same type and id to work with something like:
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
def hash
- id.hash
+ (id || object_id).hash
end
# Clone and freeze the attributes hash such that associations are still