public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Make AssociationCollection start transactions in the correct database.

AssociationCollection now starts transactions by calling
AssociationCollection#transaction instead of @owner.transaction or
@reflection.klass.transaction.

Signed-off-by: Michael Koziarski <michael@koziarski.com>

[#1081 state:committed]
Hongli Lai (Phusion) (author)
Sat Sep 20 12:59:49 -0700 2008
NZKoz (committer)
Tue Sep 23 11:32:01 -0700 2008
commit  70b8ea4fa6f432919340345ae0d5af6aa8f87ec8
tree    d23147412f49339d8671b9933ca0a5528f9313ca
parent  2e75bd0808f4dcac328b690aaad176cbfe96773e
...
108
109
110
111
 
112
113
114
...
123
124
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
127
128
...
173
174
175
176
 
177
178
179
...
200
201
202
203
 
204
205
206
...
292
293
294
295
 
296
297
298
...
108
109
110
 
111
112
113
114
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
188
189
190
 
191
192
193
194
...
215
216
217
 
218
219
220
221
...
307
308
309
 
310
311
312
313
0
@@ -108,7 +108,7 @@ module ActiveRecord
0
         result = true
0
         load_target if @owner.new_record?
0
 
0
-        @owner.transaction do
0
+        transaction do
0
           flatten_deeper(records).each do |record|
0
             raise_on_type_mismatch(record)
0
             add_record_to_target_with_callbacks(record) do |r|
0
@@ -123,6 +123,21 @@ module ActiveRecord
0
       alias_method :push, :<<
0
       alias_method :concat, :<<
0
 
0
+      # Starts a transaction in the association class's database connection.
0
+      #
0
+      #   class Author < ActiveRecord::Base
0
+      #     has_many :books
0
+      #   end
0
+      #
0
+      #   Author.find(:first).books.transaction do
0
+      #     # same effect as calling Book.transaction
0
+      #   end
0
+      def transaction(*args)
0
+        @reflection.klass.transaction(*args) do
0
+          yield
0
+        end
0
+      end
0
+
0
       # Remove all records from this association
0
       def delete_all
0
         load_target
0
@@ -173,7 +188,7 @@ module ActiveRecord
0
         records = flatten_deeper(records)
0
         records.each { |record| raise_on_type_mismatch(record) }
0
         
0
-        @owner.transaction do
0
+        transaction do
0
           records.each { |record| callback(:before_remove, record) }
0
           
0
           old_records = records.reject {|r| r.new_record? }
0
@@ -200,7 +215,7 @@ module ActiveRecord
0
       end
0
       
0
       def destroy_all
0
-        @owner.transaction do
0
+        transaction do
0
           each { |record| record.destroy }
0
         end
0
 
0
@@ -292,7 +307,7 @@ module ActiveRecord
0
         other   = other_array.size < 100 ? other_array : other_array.to_set
0
         current = @target.size < 100 ? @target : @target.to_set
0
 
0
-        @owner.transaction do
0
+        transaction do
0
           delete(@target.select { |v| !other.include?(v) })
0
           concat(other_array.select { |v| !current.include?(v) })
0
         end
...
9
10
11
12
 
13
14
15
16
17
18
19
 
20
21
22
...
9
10
11
 
12
13
14
15
16
17
18
 
19
20
21
22
0
@@ -9,14 +9,14 @@ module ActiveRecord
0
       alias_method :new, :build
0
 
0
       def create!(attrs = nil)
0
-        @reflection.klass.transaction do
0
+        transaction do
0
           self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.create_association! } : @reflection.create_association!)
0
           object
0
         end
0
       end
0
 
0
       def create(attrs = nil)
0
-        @reflection.klass.transaction do
0
+        transaction do
0
           self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.create_association } : @reflection.create_association)
0
           object
0
         end
...
738
739
740
 
 
 
 
 
 
 
 
 
741
...
738
739
740
741
742
743
744
745
746
747
748
749
750
0
@@ -738,4 +738,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
0
     # Array#count in Ruby >=1.8.7, which would raise an ArgumentError
0
     assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
0
   end
0
+
0
+  uses_mocha 'mocking Post.transaction' do
0
+    def test_association_proxy_transaction_method_starts_transaction_in_association_class
0
+      Post.expects(:transaction)
0
+      Category.find(:first).posts.transaction do
0
+        # nothing
0
+      end
0
+    end
0
+  end
0
 end
...
1071
1072
1073
 
 
 
 
 
 
 
 
 
1074
...
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
0
@@ -1071,4 +1071,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
0
     ActiveRecord::Base.store_full_sti_class = old
0
   end
0
 
0
+  uses_mocha 'mocking Comment.transaction' do
0
+    def test_association_proxy_transaction_method_starts_transaction_in_association_class
0
+      Comment.expects(:transaction)
0
+      Post.find(:first).comments.transaction do
0
+        # nothing
0
+      end
0
+    end
0
+  end
0
+
0
 end
...
220
221
222
 
 
 
 
 
 
 
 
 
223
...
220
221
222
223
224
225
226
227
228
229
230
231
232
0
@@ -220,4 +220,13 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
0
     assert_equal [posts(:welcome).id, posts(:authorless).id].sort, person.post_ids.sort
0
     assert !person.posts.loaded?
0
   end
0
+
0
+  uses_mocha 'mocking Tag.transaction' do
0
+    def test_association_proxy_transaction_method_starts_transaction_in_association_class
0
+      Tag.expects(:transaction)
0
+      Post.find(:first).tags.transaction do
0
+        # nothing
0
+      end
0
+    end
0
+  end
0
 end

Comments