我想在after_commit
和update
上为create
触发相同的功能但是我想为{{仅应用特定条件 1}}。
目前,我唯一的解决方案是复制该功能并制作两个不同的update
,如下所示:
after_commit
当然它可以工作,但它根本不会使代码干掉。我确信有更好的解决方案,但我没有在官方专栏上找到任何相关的例子doc
我想要的是这样的:
after_commit :my_method_on_update,
on: :update,
if: ->(foo) { foo.previous_changes.key?(:bar) }
after_commit :my_method_on_destroy, on: :destroy
def my_method_on_update
# stuff
end
def my_method_on_destroy
# same stuff here
end
但是after_commit :my_method,
on: :update,
if: ->(foo) { foo.previous_changes.key?(:bar) },
on: destroy
def my_method
# stuff
end
声明的两倍是错误的。
答案 0 :(得分:1)
在大多数情况下,我认为两个单独的after_commit
挂钩会更好 - 如果有很多共享代码,你可以将它提取到第三种方法,你可以从更新和创建回调中调用它。但是,如果您确实需要将所有内容保存在一个回调和一个方法中,那么您可以使用transaction_include_any_action?
来检查记录是否已创建或更新:
after_commit :my_method
def my_method
# do shared stuff for both create and update
# ...
if transaction_include_any_action?([:update])
# do stuff only for create
end
end
修改
据我了解,您希望回调在每个create
和update
上运行,但如果操作为update
并且满足某个条件,则不执行任何操作。您仍然可以使用transaction_include_any_action?
,只需在满足条件的情况下尽早返回回调方法,如下所示:
after_commit :my_method, on: [:create, :update]
def my_method
return true if transaction_include_any_action?([:update]) && previous_changes.key?(:bar)
# otherwise, continue
# ...
end
答案 1 :(得分:0)
基于@omnikron,这是我的自定义解决方案:
after_commit :my_method,
on: [:destroy, :update],
unless: :exclude_commit_hook
def exclude_commit_hook
transaction_include_any_action?([:update]) && foo.previous_changes.key?(:bar)
end
def my_method
# stuff
end