Skip to content

Commit

Permalink
update_attribute and updated_attributes! are now wrapped in a transac…
Browse files Browse the repository at this point in the history
…tion

[rails#922 state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information
Neeraj Singh authored and josevalim committed Jul 18, 2010
1 parent c2d13a9 commit 99cdea7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
8 changes: 8 additions & 0 deletions activerecord/lib/active_record/base.rb
Expand Up @@ -2664,12 +2664,20 @@ def update_attribute(name, value)
# Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will
# fail and false will be returned.
def update_attributes(attributes)
with_transaction_returning_status(:update_attributes_inside_transaction, attributes)
end

def update_attributes_inside_transaction(attributes) #:nodoc:
self.attributes = attributes
save
end

# Updates an object just like Base.update_attributes but calls save! instead of save so an exception is raised if the record is invalid.
def update_attributes!(attributes)
with_transaction_returning_status(:update_attributes_inside_transaction!, attributes)
end

def update_attributes_inside_transaction!(attributes) #:nodoc:
self.attributes = attributes
save!
end
Expand Down
23 changes: 22 additions & 1 deletion activerecord/test/cases/transactions_test.rb
Expand Up @@ -3,10 +3,12 @@
require 'models/reply'
require 'models/developer'
require 'models/book'
require 'models/author'
require 'models/post'

class TransactionTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
fixtures :topics, :developers
fixtures :topics, :developers, :authors, :posts

def setup
@first, @second = Topic.find(1, 2).sort_by { |t| t.id }
Expand Down Expand Up @@ -34,6 +36,25 @@ def transaction_with_return
end
end

def test_update_attributes_should_rollback_on_failure
author = Author.find(1)
posts_count = author.posts.size
assert posts_count > 0
status = author.update_attributes(:name => nil, :post_ids => [])
assert !status
assert_equal posts_count, author.posts(true).size
end

def test_update_attributes_should_rollback_on_failure!
author = Author.find(1)
posts_count = author.posts.size
assert posts_count > 0
assert_raise(ActiveRecord::RecordInvalid) do
author.update_attributes!(:name => nil, :post_ids => [])
end
assert_equal posts_count, author.posts(true).size
end

def test_successful_with_return
class << Topic.connection
alias :real_commit_db_transaction :commit_db_transaction
Expand Down
2 changes: 2 additions & 0 deletions activerecord/test/models/author.rb
Expand Up @@ -106,6 +106,8 @@ def label
"#{id}-#{name}"
end

validates_presence_of :name

private
def log_before_adding(object)
@post_log << "before_adding#{object.id || '<new>'}"
Expand Down

0 comments on commit 99cdea7

Please sign in to comment.