aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/persistence.rb12
-rw-r--r--activerecord/test/cases/transactions_test.rb23
-rw-r--r--activerecord/test/models/author.rb2
3 files changed, 32 insertions, 5 deletions
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index e53cc5ee8c..3681a63e03 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -121,15 +121,19 @@ module ActiveRecord
# 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)
- self.attributes = attributes
- save
+ with_transaction_returning_status do
+ self.attributes = attributes
+ save
+ end
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)
- self.attributes = attributes
- save!
+ with_transaction_returning_status do
+ self.attributes = attributes
+ save!
+ end
end
# Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 958a4e4f94..9255190613 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 }
@@ -103,6 +105,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_cancellation_from_before_destroy_rollbacks_in_destroy
add_cancelling_before_destroy_with_db_side_effect_to_topic
begin
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index 655b45bf57..727978431c 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -108,6 +108,8 @@ class Author < ActiveRecord::Base
%w(twitter github)
end
+ validates_presence_of :name
+
private
def log_before_adding(object)
@post_log << "before_adding#{object.id || '<new>'}"