mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
multiple actions for :on option with after_commit
and after_rollback
Closes #988.
This commit is contained in:
parent
b0fa9b59c8
commit
d98763a602
3 changed files with 60 additions and 14 deletions
|
@ -1,5 +1,13 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* The `:on` option for `after_commit` and `after_rollback` now
|
||||
accepts an Array of actions.
|
||||
Fixes #988.
|
||||
|
||||
Example:
|
||||
|
||||
after_commit :update_cache on: [:create, :update]
|
||||
|
||||
* Rename related indexes on `rename_table` and `rename_column`. This
|
||||
does not affect indexes with custom names.
|
||||
|
||||
|
|
|
@ -218,9 +218,8 @@ module ActiveRecord
|
|||
# after_commit :do_bar, on: :update
|
||||
# after_commit :do_baz, on: :destroy
|
||||
#
|
||||
# Also, to have the callback fired on create and update, but not on destroy:
|
||||
#
|
||||
# after_commit :do_zoo, if: :persisted?
|
||||
# after_commit :do_foo_bar, :on [:create, :update]
|
||||
# after_commit :do_bar_baz, :on [:update, :destroy]
|
||||
#
|
||||
# Note that transactional fixtures do not play well with this feature. Please
|
||||
# use the +test_after_commit+ gem to have these hooks fired in tests.
|
||||
|
@ -244,12 +243,14 @@ module ActiveRecord
|
|||
if options.is_a?(Hash) && options[:on]
|
||||
assert_valid_transaction_action(options[:on])
|
||||
options[:if] = Array(options[:if])
|
||||
options[:if] << "transaction_include_action?(:#{options[:on]})"
|
||||
fire_on = Array(options[:on]).map(&:to_sym)
|
||||
options[:if] << "transaction_include_any_action?(#{fire_on})"
|
||||
end
|
||||
end
|
||||
|
||||
def assert_valid_transaction_action(action)
|
||||
unless ACTIONS.include?(action.to_sym)
|
||||
def assert_valid_transaction_action(actions)
|
||||
actions = Array(actions)
|
||||
if (actions - ACTIONS).any?
|
||||
raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS.join(",")}"
|
||||
end
|
||||
end
|
||||
|
@ -378,14 +379,16 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
# Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
|
||||
def transaction_include_action?(action) #:nodoc:
|
||||
case action
|
||||
when :create
|
||||
transaction_record_state(:new_record)
|
||||
when :destroy
|
||||
destroyed?
|
||||
when :update
|
||||
!(transaction_record_state(:new_record) || destroyed?)
|
||||
def transaction_include_any_action?(actions) #:nodoc:
|
||||
actions.any? do |action|
|
||||
case action
|
||||
when :create
|
||||
transaction_record_state(:new_record)
|
||||
when :destroy
|
||||
destroyed?
|
||||
when :update
|
||||
!(transaction_record_state(:new_record) || destroyed?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -312,3 +312,38 @@ class SaveFromAfterCommitBlockTest < ActiveRecord::TestCase
|
|||
assert_equal true, topic.record_updated
|
||||
end
|
||||
end
|
||||
|
||||
class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
class TopicWithCallbacksOnMultipleActions < ActiveRecord::Base
|
||||
self.table_name = :topics
|
||||
|
||||
after_commit(on: [:create, :destroy]) { |record| record.history << :create_and_destroy }
|
||||
after_commit(on: [:create, :update]) { |record| record.history << :create_and_update }
|
||||
after_commit(on: [:update, :destroy]) { |record| record.history << :update_and_destroy }
|
||||
|
||||
def clear_history
|
||||
@history = []
|
||||
end
|
||||
|
||||
def history
|
||||
@history ||= []
|
||||
end
|
||||
end
|
||||
|
||||
def test_after_commit_on_multiple_actions
|
||||
topic = TopicWithCallbacksOnMultipleActions.new
|
||||
topic.save
|
||||
assert_equal [:create_and_update, :create_and_destroy], topic.history
|
||||
|
||||
topic.clear_history
|
||||
topic.approved = true
|
||||
topic.save
|
||||
assert_equal [:update_and_destroy, :create_and_update], topic.history
|
||||
|
||||
topic.clear_history
|
||||
topic.destroy
|
||||
assert_equal [:update_and_destroy, :create_and_destroy], topic.history
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue