aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb23
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb4
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb9
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb9
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb9
5 files changed, 48 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 47a09510c8..463de9d819 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -108,7 +108,7 @@ module ActiveRecord
result = true
load_target if @owner.new_record?
- @owner.transaction do
+ transaction do
flatten_deeper(records).each do |record|
raise_on_type_mismatch(record)
add_record_to_target_with_callbacks(record) do |r|
@@ -123,6 +123,21 @@ module ActiveRecord
alias_method :push, :<<
alias_method :concat, :<<
+ # Starts a transaction in the association class's database connection.
+ #
+ # class Author < ActiveRecord::Base
+ # has_many :books
+ # end
+ #
+ # Author.find(:first).books.transaction do
+ # # same effect as calling Book.transaction
+ # end
+ def transaction(*args)
+ @reflection.klass.transaction(*args) do
+ yield
+ end
+ end
+
# Remove all records from this association
def delete_all
load_target
@@ -173,7 +188,7 @@ module ActiveRecord
records = flatten_deeper(records)
records.each { |record| raise_on_type_mismatch(record) }
- @owner.transaction do
+ transaction do
records.each { |record| callback(:before_remove, record) }
old_records = records.reject {|r| r.new_record? }
@@ -200,7 +215,7 @@ module ActiveRecord
end
def destroy_all
- @owner.transaction do
+ transaction do
each { |record| record.destroy }
end
@@ -292,7 +307,7 @@ module ActiveRecord
other = other_array.size < 100 ? other_array : other_array.to_set
current = @target.size < 100 ? @target : @target.to_set
- @owner.transaction do
+ transaction do
delete(@target.select { |v| !other.include?(v) })
concat(other_array.select { |v| !current.include?(v) })
end
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index ebd2bf768c..3171665e19 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -9,14 +9,14 @@ module ActiveRecord
alias_method :new, :build
def create!(attrs = nil)
- @reflection.klass.transaction do
+ transaction do
self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.create_association! } : @reflection.create_association!)
object
end
end
def create(attrs = nil)
- @reflection.klass.transaction do
+ transaction do
self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.create_association } : @reflection.create_association)
object
end
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index c1d4ea8b50..2949f1d304 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -738,4 +738,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
# Array#count in Ruby >=1.8.7, which would raise an ArgumentError
assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
end
+
+ uses_mocha 'mocking Post.transaction' do
+ def test_association_proxy_transaction_method_starts_transaction_in_association_class
+ Post.expects(:transaction)
+ Category.find(:first).posts.transaction do
+ # nothing
+ end
+ end
+ end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 9d550916d7..315d77de07 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -1071,4 +1071,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
ActiveRecord::Base.store_full_sti_class = old
end
+ uses_mocha 'mocking Comment.transaction' do
+ def test_association_proxy_transaction_method_starts_transaction_in_association_class
+ Comment.expects(:transaction)
+ Post.find(:first).comments.transaction do
+ # nothing
+ end
+ end
+ end
+
end
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 0be050ec81..12cce98c26 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -220,4 +220,13 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_equal [posts(:welcome).id, posts(:authorless).id].sort, person.post_ids.sort
assert !person.posts.loaded?
end
+
+ uses_mocha 'mocking Tag.transaction' do
+ def test_association_proxy_transaction_method_starts_transaction_in_association_class
+ Tag.expects(:transaction)
+ Post.find(:first).tags.transaction do
+ # nothing
+ end
+ end
+ end
end