public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Ensure HABTM#create and HABTM#build do not load entire association. [Pratik]


git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9229 
5ecf4fe2-1ee6-0310-87b1-e25e094e27de
lifo (author)
Sat Apr 05 09:25:48 -0700 2008
commit  15d88885eedbac1193361a9eea957a7f49e39c9e
tree    9e035506df3e50f4bbffb10c29f33f73d47097ba
parent  77730f7c9dc2e28e7f3c84ce647b84eb470dd819
...
1
2
 
 
3
4
5
...
1
2
3
4
5
6
7
0
@@ -1,5 +1,7 @@
0
 *SVN*
0
 
0
+* Ensure HABTM#create and HABTM#build do not load entire association. [Pratik]
0
+
0
 * Improve documentation. [Xavier Noria, Jack Danger Canty, leethal]
0
 
0
 * Tweak ActiveRecord::Base#to_json to include a root value in the returned hash: {"post": {"title": ...}} [rick]
...
166
167
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
170
171
...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
0
@@ -166,6 +166,25 @@ module ActiveRecord
0
       end
0
 
0
       protected
0
+        def load_target
0
+          if !@owner.new_record? || foreign_key_present
0
+            begin
0
+              if !loaded?
0
+                if @target.is_a?(Array) && @target.any?
0
+                  @target = find_target + @target.find_all {|t| t.new_record? }
0
+                else
0
+                  @target = find_target
0
+                end
0
+              end
0
+            rescue ActiveRecord::RecordNotFound
0
+              reset
0
+            end
0
+          end
0
+
0
+          loaded if target
0
+          target
0
+        end
0
+        
0
         def method_missing(method, *args)
0
           if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
0
             if block_given?
...
7
8
9
10
11
12
13
...
154
155
156
157
158
159
160
...
7
8
9
 
10
11
12
...
153
154
155
 
156
157
158
0
@@ -7,7 +7,6 @@ module ActiveRecord
0
       end
0
 
0
       def build(attributes = {})
0
-        load_target
0
         build_record(attributes)
0
       end
0
 
0
@@ -154,7 +153,6 @@ module ActiveRecord
0
           if attributes.is_a?(Array)
0
             attributes.collect { |attr| create(attr) }
0
           else
0
-            load_target
0
             build_record(attributes, &block)
0
           end
0
         end
...
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
68
69
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
72
73
0
@@ -68,25 +68,6 @@ module ActiveRecord
0
       end
0
 
0
       protected
0
-        def load_target
0
-          if !@owner.new_record? || foreign_key_present
0
-            begin
0
-              if !loaded?
0
-                if @target.is_a?(Array) && @target.any?
0
-                  @target = (find_target + @target).uniq
0
-                else
0
-                  @target = find_target
0
-                end
0
-              end
0
-            rescue ActiveRecord::RecordNotFound
0
-              reset
0
-            end
0
-          end
0
-
0
-          loaded if target
0
-          target
0
-        end
0
-
0
         def count_records
0
           count = if has_cached_counter?
0
             @owner.send(:read_attribute, cached_counter_attribute_name)
...
872
873
874
875
 
 
 
 
876
877
878
879
 
 
880
881
 
882
883
884
885
 
 
 
886
887
888
889
 
 
890
891
892
...
1908
1909
1910
1911
 
 
 
1912
 
 
1913
1914
1915
...
1933
1934
1935
 
 
1936
 
 
1937
1938
1939
...
1964
1965
1966
1967
1968
1969
1970
 
 
 
 
 
 
1971
1972
1973
...
872
873
874
 
875
876
877
878
879
880
 
 
881
882
883
 
884
885
886
887
 
888
889
890
891
 
 
 
892
893
894
895
896
...
1912
1913
1914
 
1915
1916
1917
1918
1919
1920
1921
1922
1923
...
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
...
1976
1977
1978
 
 
 
 
1979
1980
1981
1982
1983
1984
1985
1986
1987
0
@@ -872,21 +872,25 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
   end
0
 
0
   def test_build
0
-    new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
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
     assert_equal "Another Client", new_client.name
0
     assert new_client.new_record?
0
-    assert_equal new_client, companies(:first_firm).clients_of_firm.last
0
-    assert companies(:first_firm).save
0
+    assert_equal new_client, company.clients_of_firm.last
0
+    assert_queries(2) { assert company.save }
0
     assert !new_client.new_record?
0
-    assert_equal 2, companies(:first_firm).clients_of_firm(true).size
0
+    assert_equal 2, company.clients_of_firm(true).size
0
   end
0
 
0
   def test_build_many
0
-    new_clients = companies(:first_firm).clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}])
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
     assert_equal 2, new_clients.size
0
-
0
-    assert companies(:first_firm).save
0
-    assert_equal 3, companies(:first_firm).clients_of_firm(true).size
0
+    assert_queries(3) { assert company.save }
0
+    assert_equal 3, company.clients_of_firm(true).size
0
   end
0
 
0
   def test_build_followed_by_save_does_not_load_target
0
@@ -1908,8 +1912,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
 
0
   def test_build
0
     devel = Developer.find(1)
0
-    proj = devel.projects.build("name" => "Projekt")
0
+    proj = assert_no_queries { devel.projects.build("name" => "Projekt") }
0
+    assert !devel.projects.loaded?
0
+    
0
     assert_equal devel.projects.last, proj
0
+    assert devel.projects.loaded?
0
+    
0
     assert proj.new_record?
0
     devel.save
0
     assert !proj.new_record?
0
@@ -1933,7 +1941,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
   def test_create
0
     devel = Developer.find(1)
0
     proj = devel.projects.create("name" => "Projekt")
0
+    assert !devel.projects.loaded?
0
+    
0
     assert_equal devel.projects.last, proj
0
+    assert devel.projects.loaded?
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
@@ -1964,10 +1976,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
   end
0
 
0
   def test_uniq_after_the_fact
0
-    developers(:jamis).projects << projects(:active_record)
0
-    developers(:jamis).projects << projects(:active_record)
0
-    assert_equal 3, developers(:jamis).projects.size
0
-    assert_equal 1, developers(:jamis).projects.uniq.size
0
+    dev = developers(:jamis)
0
+    dev.projects << projects(:active_record)
0
+    dev.projects << projects(:active_record)
0
+    
0
+    assert_equal 3, dev.projects.size
0
+    assert_equal 1, dev.projects.uniq.size
0
   end
0
 
0
   def test_uniq_before_the_fact

Comments