提交 5a300b2e 编写于 作者: G Genadi Samokovarov

Introduce after_{create,update,delete}_commit callbacks

Those are actually shortcuts for `after_commit`.

Before:

    after_commit :add_to_index_later, on: :create
    after_commit :update_in_index_later, on: :update
    after_commit :remove_from_index_later, on: :destroy

After:

    after_create_commit  :add_to_index_later
    after_update_commit  :update_in_index_later
    after_destroy_commit :remove_from_index_later
上级 65443ceb
* Introduce after_{create,update,delete}_commit callbacks.
Before:
after_commit :add_to_index_later, on: :create
after_commit :update_in_index_later, on: :update
after_commit :remove_from_index_later, on: :destroy
After:
after_create_commit :add_to_index_later
after_update_commit :update_in_index_later
after_destroy_commit :remove_from_index_later
Fixes #22515.
*Genadi Samokovarov*
* Respect the column default values for `inheritance_column` when
instantiating records through the base class.
......
......@@ -233,6 +233,24 @@ def after_commit(*args, &block)
set_callback(:commit, :after, *args, &block)
end
# Shortcut for +after_commit :hook, on: :create+.
def after_create_commit(*args, &block)
set_options_for_callbacks!(args, on: :create)
set_callback(:commit, :after, *args, &block)
end
# Shortcut for +after_commit :hook, on: :update+.
def after_update_commit(*args, &block)
set_options_for_callbacks!(args, on: :update)
set_callback(:commit, :after, *args, &block)
end
# Shortcut for +after_commit :hook, on: :destroy+.
def after_destroy_commit(*args, &block)
set_options_for_callbacks!(args, on: :destroy)
set_callback(:commit, :after, *args, &block)
end
# This callback is called after a create, update, or destroy are rolled back.
#
# Please check the documentation of #after_commit for options.
......@@ -268,9 +286,11 @@ def raise_in_transactional_callbacks=(value)
private
def set_options_for_callbacks!(args)
options = args.last
if options.is_a?(Hash) && options[:on]
def set_options_for_callbacks!(args, enforced_options = {})
options = args.extract_options!.merge!(enforced_options)
args << options
if options[:on]
fire_on = Array(options[:on])
assert_valid_transaction_action(fire_on)
options[:if] = Array(options[:if])
......
......@@ -35,9 +35,9 @@ class TopicWithCallbacks < ActiveRecord::Base
has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
after_commit { |record| record.do_after_commit(nil) }
after_commit(on: :create) { |record| record.do_after_commit(:create) }
after_commit(on: :update) { |record| record.do_after_commit(:update) }
after_commit(on: :destroy) { |record| record.do_after_commit(:destroy) }
after_create_commit { |record| record.do_after_commit(:create) }
after_update_commit { |record| record.do_after_commit(:update) }
after_destroy_commit { |record| record.do_after_commit(:destroy) }
after_rollback { |record| record.do_after_rollback(nil) }
after_rollback(on: :create) { |record| record.do_after_rollback(:create) }
after_rollback(on: :update) { |record| record.do_after_rollback(:update) }
......
......@@ -412,4 +412,23 @@ end
NOTE: the `:on` option specifies when a callback will be fired. If you
don't supply the `:on` option the callback will fire for every action.
Since using `after_commit` callback only on create, update or delete is
common, there are aliases for those operations:
* `after_create_commit`
* `after_update_commit`
* `after_destroy_commit`
```ruby
class PictureFile < ActiveRecord::Base
after_destroy_commit :delete_picture_file_from_disk
def delete_picture_file_from_disk
if File.exist?(filepath)
File.delete(filepath)
end
end
end
```
WARNING. The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册