From ed1ed05fbeebfda69072e0ac0198cf05707cbedf Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Wed, 14 Jul 2010 10:45:33 -0400 Subject: [PATCH] update_attribute and updated_attributes! are now wrapped in a transaction [#922 state:resolved] --- activerecord/lib/active_record/base.rb | 8 ++++++++ activerecord/test/cases/transactions_test.rb | 23 ++++++++++++++++++++++- activerecord/test/models/author.rb | 2 ++ 3 files changed, 32 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 0ba2c9e..e6391cb 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2663,12 +2663,20 @@ module ActiveRecord #:nodoc: # 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 diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index f6533b5..a4184d8 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -3,10 +3,12 @@ require 'models/topic' 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 } @@ -34,6 +36,25 @@ class TransactionTest < ActiveRecord::TestCase 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 diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index 586eb0b..fbbdaea 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -106,6 +106,8 @@ class Author < ActiveRecord::Base "#{id}-#{name}" end + validates_presence_of :name + private def log_before_adding(object) @post_log << "before_adding#{object.id || ''}" -- 1.6.5.2