public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Performance: Better query for ASSOCIATION_ids. Select only ids if the 
association hasn't been loaded.

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
miloops (author)
Sat Aug 30 15:17:29 -0700 2008
jeremy (committer)
Sat Aug 30 15:24:09 -0700 2008
commit  b163d83b8bab9103dc0e73b86212c2629cb45ca2
tree    c19d54af0323dad322016499f8c6ee7dee8bb82c
parent  afea4c9b0edb895d3d7ded6bbf45fc55739a96c6
...
1304
1305
1306
1307
 
 
 
 
 
1308
1309
1310
...
1304
1305
1306
 
1307
1308
1309
1310
1311
1312
1313
1314
0
@@ -1304,7 +1304,11 @@ module ActiveRecord
0
           end
0
 
0
           define_method("#{reflection.name.to_s.singularize}_ids") do
0
-            send(reflection.name).map { |record| record.id }
0
+            if send(reflection.name).loaded?
0
+              send(reflection.name).map(&:id)
0
+            else
0
+              send(reflection.name).all(:select => "#{reflection.quoted_table_name}.id").map(&:id)
0
+            end
0
           end
0
         end
0
 
...
223
224
225
226
 
227
228
229
 
230
231
232
...
251
252
253
254
 
255
256
257
 
258
259
260
...
274
275
276
277
 
278
279
280
 
281
282
283
...
288
289
290
291
 
292
293
294
...
415
416
417
418
 
419
420
421
422
423
424
 
425
426
427
...
641
642
643
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
644
645
646
...
223
224
225
 
226
227
228
 
229
230
231
232
...
251
252
253
 
254
255
256
 
257
258
259
260
...
274
275
276
 
277
278
279
 
280
281
282
283
...
288
289
290
 
291
292
293
294
...
415
416
417
 
418
419
420
421
422
423
 
424
425
426
427
...
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
0
@@ -223,10 +223,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
     devel = Developer.find(1)
0
     proj = assert_no_queries { devel.projects.build("name" => "Projekt") }
0
     assert !devel.projects.loaded?
0
-    
0
+
0
     assert_equal devel.projects.last, proj
0
     assert devel.projects.loaded?
0
-    
0
+
0
     assert proj.new_record?
0
     devel.save
0
     assert !proj.new_record?
0
@@ -251,10 +251,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
     devel = Developer.find(1)
0
     proj = devel.projects.create("name" => "Projekt")
0
     assert !devel.projects.loaded?
0
-    
0
+
0
     assert_equal devel.projects.last, proj
0
     assert devel.projects.loaded?
0
-    
0
+
0
     assert !proj.new_record?
0
     assert_equal Developer.find(1).projects.sort_by(&:id).last, proj  # prove join table is updated
0
   end
0
@@ -274,10 +274,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
 
0
   def test_creation_respects_hash_condition
0
     post = categories(:general).post_with_conditions.build(:body => '')
0
-    
0
+
0
     assert        post.save
0
     assert_equal  'Yet Another Testing Title', post.title
0
-    
0
+
0
     another_post = categories(:general).post_with_conditions.create(:body => '')
0
 
0
     assert        !another_post.new_record?
0
@@ -288,7 +288,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
     dev = developers(:jamis)
0
     dev.projects << projects(:active_record)
0
     dev.projects << projects(:active_record)
0
-    
0
+
0
     assert_equal 3, dev.projects.size
0
     assert_equal 1, dev.projects.uniq.size
0
   end
0
@@ -415,13 +415,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
     project.developers.class # force load target
0
 
0
     developer = project.developers.first
0
-    
0
+
0
     assert_no_queries do
0
       assert project.developers.loaded?
0
       assert project.developers.include?(developer)
0
     end
0
   end
0
-  
0
+
0
   def test_include_checks_if_record_exists_if_target_not_loaded
0
     project = projects(:active_record)
0
     developer = project.developers.first
0
@@ -641,6 +641,22 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
     assert_equal [projects(:active_record).id], developers(:jamis).project_ids
0
   end
0
 
0
+  def test_get_ids_for_loaded_associations
0
+    developer = developers(:david)
0
+    developer.projects(true)
0
+    assert_queries(0) do
0
+      developer.project_ids
0
+      developer.project_ids
0
+    end
0
+  end
0
+
0
+  def test_get_ids_for_unloaded_associations_does_not_load_them
0
+    developer = developers(:david)
0
+    assert !developer.projects.loaded?
0
+    assert_equal projects(:active_record, :action_controller).map(&:id).sort, developer.project_ids.sort
0
+    assert !developer.projects.loaded?
0
+  end
0
+
0
   def test_assign_ids
0
     developer = Developer.new("name" => "Joe")
0
     developer.project_ids = projects(:active_record, :action_controller).map(&:id)
...
384
385
386
387
 
388
389
390
...
416
417
418
419
 
420
421
422
...
655
656
657
658
 
659
660
661
 
662
663
664
...
830
831
832
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
833
834
835
...
900
901
902
903
 
904
905
906
...
937
938
939
940
 
941
942
943
944
945
946
 
947
948
949
...
384
385
386
 
387
388
389
390
...
416
417
418
 
419
420
421
422
...
655
656
657
 
658
659
660
 
661
662
663
664
...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
...
916
917
918
 
919
920
921
922
...
953
954
955
 
956
957
958
959
960
961
 
962
963
964
965
0
@@ -384,7 +384,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
     company = companies(:first_firm)
0
     new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
0
     assert !company.clients_of_firm.loaded?
0
-    
0
+
0
     assert_equal "Another Client", new_client.name
0
     assert new_client.new_record?
0
     assert_equal new_client, company.clients_of_firm.last
0
@@ -416,7 +416,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
   def test_build_many
0
     company = companies(:first_firm)
0
     new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
0
-    
0
+
0
     assert_equal 2, new_clients.size
0
     company.name += '-changed'
0
     assert_queries(3) { assert company.save }
0
@@ -655,10 +655,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
 
0
   def test_creation_respects_hash_condition
0
     ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.build
0
-    
0
+
0
     assert        ms_client.save
0
     assert_equal  'Microsoft', ms_client.name
0
-    
0
+
0
     another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create
0
 
0
     assert        !another_ms_client.new_record?
0
@@ -830,6 +830,22 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
     assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
0
   end
0
 
0
+  def test_get_ids_for_loaded_associations
0
+    company = companies(:first_firm)
0
+    company.clients(true)
0
+    assert_queries(0) do
0
+      company.client_ids
0
+      company.client_ids
0
+    end
0
+  end
0
+
0
+  def test_get_ids_for_unloaded_associations_does_not_load_them
0
+    company = companies(:first_firm)
0
+    assert !company.clients.loaded?
0
+    assert_equal [companies(:first_client).id, companies(:second_client).id], company.client_ids
0
+    assert !company.clients.loaded?
0
+  end
0
+
0
   def test_assign_ids
0
     firm = Firm.new("name" => "Apple")
0
     firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
0
@@ -900,7 +916,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
     assert_equal 4, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'", :limit => 9_000).length
0
     assert_equal 4, authors(:david).limited_comments.find_all_by_type('SpecialComment', :limit => 9_000).length
0
   end
0
-  
0
+
0
   def test_find_all_include_over_the_same_table_for_through
0
     assert_equal 2, people(:michael).posts.find(:all, :include => :people).length
0
   end
0
@@ -937,13 +953,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
   def test_include_loads_collection_if_target_uses_finder_sql
0
     firm = companies(:first_firm)
0
     client = firm.clients_using_sql.first
0
-    
0
+
0
     firm.reload
0
     assert ! firm.clients_using_sql.loaded?
0
     assert firm.clients_using_sql.include?(client)
0
     assert firm.clients_using_sql.loaded?
0
   end
0
-  
0
+
0
 
0
   def test_include_returns_false_for_non_matching_record_to_verify_scoping
0
     firm = companies(:first_firm)
...
200
201
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
0
@@ -200,4 +200,24 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
0
   def test_count_with_include_should_alias_join_table
0
     assert_equal 2, people(:michael).posts.count(:include => :readers)
0
   end
0
+
0
+  def test_get_ids
0
+    assert_equal [posts(:welcome).id, posts(:authorless).id], people(:michael).post_ids
0
+  end
0
+
0
+  def test_get_ids_for_loaded_associations
0
+    person = people(:michael)
0
+    person.posts(true)
0
+    assert_queries(0) do
0
+      person.post_ids
0
+      person.post_ids
0
+    end
0
+  end
0
+
0
+  def test_get_ids_for_unloaded_associations_does_not_load_them
0
+    person = people(:michael)
0
+    assert !person.posts.loaded?
0
+    assert_equal [posts(:welcome).id, posts(:authorless).id], person.post_ids
0
+    assert !person.posts.loaded?
0
+  end
0
 end

Comments