From 9dbb72a7ac836fbf8e162adc41dd3bb3c0a333a5 Mon Sep 17 00:00:00 2001 From: Brad Pauly Date: Fri, 24 Apr 2009 23:35:53 -0700 Subject: [PATCH] has_many transaction rollback --- activerecord/lib/active_record/transactions.rb | 12 +++++++++++- activerecord/test/cases/transactions_test.rb | 23 +++++++++++++++++++++++ activerecord/test/models/developer.rb | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index b059eb7..28ffc70 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -10,7 +10,7 @@ module ActiveRecord base.extend(ClassMethods) base.class_eval do - [:destroy, :save, :save!].each do |method| + [:destroy, :save, :save!, :update_attributes, :update_attributes!].each do |method| alias_method_chain method, :transactions end end @@ -202,6 +202,16 @@ module ActiveRecord rollback_active_record_state! { self.class.transaction { save_without_transactions! } } end + def update_attributes_with_transactions(attributes) + with_transaction_returning_status(:update_attributes_without_transactions, attributes) + end + + def update_attributes_with_transactions!(attributes) + transaction do + update_attributes_without_transactions!(attributes) + end + end + # Reset id and @new_record if the transaction rolls back. def rollback_active_record_state! id_present = has_attribute?(self.class.primary_key) diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index f6533b5..1ce85a4 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -182,6 +182,29 @@ class TransactionTest < ActiveRecord::TestCase end end + def test_update_attributes_should_rollback_on_failure + developer = Developer.find(:first) + logs_size = developer.audit_logs.size + new_logs_size = 2 + logs_size + 2.times { developer.audit_logs.create(:message => 'audited') } + assert_equal new_logs_size, developer.audit_logs.size + status = developer.update_attributes(:name => 'Nu', :audit_log_ids => []) + assert !status + assert_equal new_logs_size, developer.audit_logs(true).size + end + + def test_update_attributes_should_rollback_on_failure! + developer = Developer.find(:first) + logs_size = developer.audit_logs.size + new_logs_size = 2 + logs_size + 2.times { developer.audit_logs.create(:message => 'audited') } + assert_equal new_logs_size, developer.audit_logs.size + assert_raise(ActiveRecord::RecordInvalid) do + developer.update_attributes!(:audit_log_ids => [], :name => nil) + end + assert_equal new_logs_size, developer.audit_logs(true).size + end + def test_nested_explicit_transactions Topic.transaction do Topic.transaction do diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 92039a4..4d980a3 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -41,7 +41,7 @@ class Developer < ActiveRecord::Base has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id' - has_many :audit_logs + has_many :audit_logs, :dependent => :destroy named_scope :jamises, :conditions => {:name => 'Jamis'} -- 1.6.0.1