Rails 4 after_commit嵌套条件问题

时间:2016-12-30 10:44:06

标签: ruby-on-rails ruby-on-rails-4 callback

我想在after_commitupdate上为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 声明的两倍是错误的。

2 个答案:

答案 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

修改

据我了解,您希望回调在每个createupdate上运行,但如果操作为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