From 327103fddd495a074678159265cab49b031cd5ab Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Wed, 7 May 2008 00:12:17 +0100 Subject: [PATCH] When preloading group by reflection rather than by class This avoids extra queries when several subclasses inherit the association from their parent class, while still coping with subclasses redefining associations. --- .../lib/active_record/association_preload.rb | 12 ++++++------ activerecord/test/cases/associations/eager_test.rb | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index da4ebde..f0a1e88 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -31,12 +31,12 @@ module ActiveRecord private def preload_one_association(records, association, preload_options={}) - reflection = reflections[association] - raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection - - # Not all records have the same class, so group then preload. - records.group_by(&:class).each do |klass, records| - reflection = klass.reflections[association] + class_to_reflection = {} + # Not all records have the same class, so group then preload + # group on the reflection itself so that if various subclass share the same association then we do not split them + # unncessarily + records.group_by {|record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, records| + raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection send("preload_#{reflection.macro}_association", records, reflection, preload_options) end end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 67b57ce..f002afd 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -592,4 +592,10 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15") end end + + def test_load_with_sti_sharing_association + assert_queries(2) do #should not do 1 query per subclass + Comment.find :all, :include => :post + end + end end -- 1.5.4.4