Skip to content
This repository
Browse code

update_attribute and updated_attributes! are now wrapped in a transac…

…tion

[#922 state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information...
commit 99cdea7cbe69f7ea9ef82bdcf9502e47e9e4e07b 1 parent c2d13a9
Neeraj Singh authored July 14, 2010 josevalim committed July 18, 2010
8  activerecord/lib/active_record/base.rb
@@ -2664,12 +2664,20 @@ def update_attribute(name, value)
2664 2664
       # Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will
2665 2665
       # fail and false will be returned.
2666 2666
       def update_attributes(attributes)
  2667
+        with_transaction_returning_status(:update_attributes_inside_transaction, attributes)
  2668
+      end
  2669
+
  2670
+      def update_attributes_inside_transaction(attributes) #:nodoc:
2667 2671
         self.attributes = attributes
2668 2672
         save
2669 2673
       end
2670 2674
 
2671 2675
       # Updates an object just like Base.update_attributes but calls save! instead of save so an exception is raised if the record is invalid.
2672 2676
       def update_attributes!(attributes)
  2677
+        with_transaction_returning_status(:update_attributes_inside_transaction!, attributes)
  2678
+      end
  2679
+
  2680
+      def update_attributes_inside_transaction!(attributes) #:nodoc:
2673 2681
         self.attributes = attributes
2674 2682
         save!
2675 2683
       end
23  activerecord/test/cases/transactions_test.rb
@@ -3,10 +3,12 @@
3 3
 require 'models/reply'
4 4
 require 'models/developer'
5 5
 require 'models/book'
  6
+require 'models/author'
  7
+require 'models/post'
6 8
 
7 9
 class TransactionTest < ActiveRecord::TestCase
8 10
   self.use_transactional_fixtures = false
9  
-  fixtures :topics, :developers
  11
+  fixtures :topics, :developers, :authors, :posts
10 12
 
11 13
   def setup
12 14
     @first, @second = Topic.find(1, 2).sort_by { |t| t.id }
@@ -34,6 +36,25 @@ def transaction_with_return
34 36
     end
35 37
   end
36 38
 
  39
+  def test_update_attributes_should_rollback_on_failure
  40
+    author = Author.find(1)
  41
+    posts_count = author.posts.size
  42
+    assert posts_count > 0
  43
+    status = author.update_attributes(:name => nil, :post_ids => [])
  44
+    assert !status
  45
+    assert_equal posts_count, author.posts(true).size
  46
+  end
  47
+
  48
+  def test_update_attributes_should_rollback_on_failure!
  49
+    author = Author.find(1)
  50
+    posts_count = author.posts.size
  51
+    assert posts_count > 0
  52
+    assert_raise(ActiveRecord::RecordInvalid) do
  53
+      author.update_attributes!(:name => nil, :post_ids => [])
  54
+    end
  55
+    assert_equal posts_count, author.posts(true).size
  56
+  end
  57
+
37 58
   def test_successful_with_return
38 59
     class << Topic.connection
39 60
       alias :real_commit_db_transaction :commit_db_transaction
2  activerecord/test/models/author.rb
@@ -106,6 +106,8 @@ def label
106 106
     "#{id}-#{name}"
107 107
   end
108 108
 
  109
+  validates_presence_of :name
  110
+
109 111
   private
110 112
     def log_before_adding(object)
111 113
       @post_log << "before_adding#{object.id || '<new>'}"

0 notes on commit 99cdea7

Please sign in to comment.
Something went wrong with that request. Please try again.