Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix transaction state not changing when after record gets commited

  • Loading branch information...
commit 44d1804b0a86de02865c48c552bbc57da3dc7836 1 parent beea9f5
@gnufied gnufied authored
View
8 activerecord/lib/active_record/transactions.rb
@@ -302,12 +302,8 @@ def with_transaction_returning_status
def remember_transaction_record_state #:nodoc:
@_start_transaction_state ||= {}
@_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
- unless @_start_transaction_state.include?(:new_record)
- @_start_transaction_state[:new_record] = @new_record
- end
- unless @_start_transaction_state.include?(:destroyed)
- @_start_transaction_state[:destroyed] = @destroyed
- end
+ @_start_transaction_state[:new_record] = @new_record
+ @_start_transaction_state[:destroyed] = @destroyed
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
end
View
25 activerecord/test/cases/transaction_callbacks_test.rb
@@ -290,3 +290,28 @@ def test_after_rollback_called
assert_equal %w{ after_rollback }, topic.history
end
end
+
+class SaveFromAfterCommitBlockTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+
+ class TopicWithSaveInCallback < ActiveRecord::Base
+ self.table_name = :topics
+ after_commit :cache_topic, :on => :create
+ attr_accessor :cached
+
+ def cache_topic
+ unless cached
+ self.cached = true
+ self.save
+ else
+ self.cached = false
+ end
+ end
+ end
+
+ def test_after_commit_in_save
+ topic = TopicWithSaveInCallback.new()
+ topic.save
+ assert_equal true, topic.cached
+ end
+end

4 comments on commit 44d1804

@jjb

would be great if this were backported to 3.2-stable #8577 /cc @sidonath

@sidonath

This commit breaks the functionality of after_commit(on: :create) when a model instance is saved within the same transaction in which it was created (see #8937)

@gnufied

I think functionality only breaks when you have multiple after_create blocks registered. I can't imagine why anyone will call save! from following callbacks:

after_commit {} # without condition
after_commit(on: :update) {} 

Both will trigger infinite loop.

@sidonath

@gnufied it breaks when there is only one after_create block in which save is called. There's no need to call save in after_commit to trigger the problem.

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