diff options
author | Mark McSpadden <markmcspadden@gmail.com> | 2012-03-21 04:34:32 -0400 |
---|---|---|
committer | Mark McSpadden <markmcspadden@gmail.com> | 2012-03-21 04:35:28 -0400 |
commit | c8792c7b2ea4f5fe7a5610225433ea8dd8d0f83e (patch) | |
tree | 8d297eebafd05b81a5d72f981dc06678943633b8 /activerecord | |
parent | 14b2cf6a0ae2bfd60efb7c3146145bf005853cc3 (diff) | |
download | rails-c8792c7b2ea4f5fe7a5610225433ea8dd8d0f83e.tar.gz rails-c8792c7b2ea4f5fe7a5610225433ea8dd8d0f83e.tar.bz2 rails-c8792c7b2ea4f5fe7a5610225433ea8dd8d0f83e.zip |
Allow manual rollbacks in after_save to reset object correctly
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/transactions.rb | 10 | ||||
-rw-r--r-- | activerecord/test/cases/transaction_callbacks_test.rb | 37 |
2 files changed, 46 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 743dfc5a38..64107d86a8 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -290,7 +290,15 @@ module ActiveRecord status = nil self.class.transaction do add_to_transaction - status = yield + begin + status = yield + rescue ActiveRecord::Rollback + if defined?(@_start_transaction_state) + @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 + end + status = nil + end + raise ActiveRecord::Rollback unless status end status diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb index f8b3e01a49..71551c6dcc 100644 --- a/activerecord/test/cases/transaction_callbacks_test.rb +++ b/activerecord/test/cases/transaction_callbacks_test.rb @@ -287,6 +287,43 @@ class TransactionObserverCallbacksTest < ActiveRecord::TestCase raise ActiveRecord::Rollback end + assert topic.id.nil? + assert !topic.persisted? assert_equal %w{ after_rollback }, topic.history end + + class TopicWithManualRollbackObserverAttached < ActiveRecord::Base + self.table_name = :topics + def history + @history ||= [] + end + end + + class TopicWithManualRollbackObserverAttachedObserver < ActiveRecord::Observer + def after_save(record) + record.history.push "after_save" + raise ActiveRecord::Rollback + end + end + + def test_after_save_called_with_manual_rollback + assert TopicWithManualRollbackObserverAttachedObserver.instance, 'should have observer' + + topic = TopicWithManualRollbackObserverAttached.new + + assert !topic.save + assert_equal nil, topic.id + assert !topic.persisted? + assert_equal %w{ after_save }, topic.history + end + def test_after_save_called_with_manual_rollback_bang + assert TopicWithManualRollbackObserverAttachedObserver.instance, 'should have observer' + + topic = TopicWithManualRollbackObserverAttached.new + + topic.save! + assert_equal nil, topic.id + assert !topic.persisted? + assert_equal %w{ after_save }, topic.history + end end |