public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
When preloading group by reflection rather than by class [#125 state:resolved]

This avoids extra queries when several subclasses inherit the association
from their parent class, while still coping with subclasses redefining
associations.

Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
fcheung (author)
Tue May 06 16:12:17 -0700 2008
lifo (committer)
Sun May 11 14:14:07 -0700 2008
commit  236f0bb67adecbc1e6dac5258e4a8cb310ffd7a4
tree    aaca136f3ba80f589e24595cd953f064697ef0bb
parent  0cbdd96c349c56c47299ca3c2bfa5d8c4f5e5a11
...
31
32
33
34
35
36
37
38
39
 
 
 
 
 
 
40
41
42
...
31
32
33
 
 
 
 
 
 
34
35
36
37
38
39
40
41
42
0
@@ -31,12 +31,12 @@ module ActiveRecord
0
       private
0
 
0
       def preload_one_association(records, association, preload_options={})
0
-        reflection = reflections[association]
0
-        raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
0
-
0
-        # Not all records have the same class, so group then preload.
0
-        records.group_by(&:class).each do |klass, records|
0
-          reflection = klass.reflections[association]
0
+        class_to_reflection = {}
0
+        # Not all records have the same class, so group then preload
0
+        # group on the reflection itself so that if various subclass share the same association then we do not split them
0
+        # unncessarily
0
+        records.group_by {|record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, records|
0
+          raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
0
           send("preload_#{reflection.macro}_association", records, reflection, preload_options)
0
         end
0
       end
...
603
604
605
 
 
 
 
 
 
606
...
603
604
605
606
607
608
609
610
611
612
0
@@ -603,4 +603,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
0
       assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
0
     end
0
   end
0
+
0
+  def test_load_with_sti_sharing_association
0
+    assert_queries(2) do #should not do 1 query per subclass
0
+      Comment.find :all, :include => :post
0
+    end
0
+  end
0
 end

Comments