Skip to content

Commit

Permalink
Wrap calls to update_attributes in a transaction.
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#922 state:committed]
  • Loading branch information
fxn authored and NZKoz committed Feb 22, 2009
1 parent f4391c3 commit fc09ebc
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
16 changes: 15 additions & 1 deletion activerecord/lib/active_record/transactions.rb
Expand Up @@ -10,7 +10,7 @@ def self.included(base)
base.extend(ClassMethods)

base.class_eval do
[:destroy, :save, :save!].each do |method|
[:destroy, :save, :save!, :update_attribute, :update_attributes, :update_attributes!].each do |method|
alias_method_chain method, :transactions
end
end
Expand Down Expand Up @@ -200,6 +200,20 @@ def save_with_transactions! #:nodoc:
rollback_active_record_state! { self.class.transaction { save_without_transactions! } }
end

def update_attribute_with_transactions(name, value)
with_transaction_returning_status(:update_attribute_without_transactions, name, value)
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)
Expand Down
34 changes: 34 additions & 0 deletions activerecord/test/cases/transactions_test.rb
Expand Up @@ -182,6 +182,40 @@ def test_callback_rollback_in_create
end
end

def test_update_attribute_should_rollback_on_failure
Developer.before_save do
false
end
developer = Developer.first
developer.audit_logs.clear
2.times { developer.audit_logs.create(:message => 'message') }
assert_equal 2, developer.audit_logs.size
status = developer.update_attribute(:audit_log_ids, [])
assert !status
assert_equal 2, developer.audit_logs(true).size
end

def test_update_attributes_should_rollback_on_failure
developer = Developer.first
developer.audit_logs.clear
2.times { developer.audit_logs.create(:message => 'message') }
assert_equal 2, developer.audit_logs.size
status = developer.update_attributes(:audit_log_ids => [], :name => nil)
assert !status
assert_equal 2, developer.audit_logs(true).size
end

def test_update_attributes_should_rollback_on_failure!
developer = Developer.first
developer.audit_logs.clear
2.times { developer.audit_logs.create(:message => 'message') }
assert_equal 2, developer.audit_logs.size
assert_raise(ActiveRecord::RecordInvalid) do
developer.update_attributes!(:audit_log_ids => [], :name => nil)
end
assert_equal 2, developer.audit_logs(true).size
end

def test_nested_explicit_transactions
Topic.transaction do
Topic.transaction do
Expand Down

0 comments on commit fc09ebc

Please sign in to comment.