如何在使用Rails 5.2的红宝石模型中的过滤器之前跳过?

时间:2018-10-31 22:11:31

标签: ruby-on-rails before-filter

我的应用程序管理文档的层次结构。每个文档都有一个层次结构索引,该索引仅在创建时计算。文件document.rb以

开头
class BusinessRule < ActiveRecord::Base
### before filter
  before_create :set_hierarchy

并且层次结构是基于父级和兄弟级计算的,因此self.hierarchy = last_one.next在父级范围内进行评估。

现在,我添加了版本管理功能。由于在控制器中添加了new_version方法,因此使用@document.dup方法来复制文档,然后将其保存:层次结构应该保持不变,并且仅需要增加版本号。

好。 但是before_create过滤器是由模型中的save操作触发的,并且层次结构增加了,不符合要求。

如何在控制器中执行new_version操作时阻止模型中的before过滤器触发?

2 个答案:

答案 0 :(得分:3)

我不确定这是否是最好的方法,但是我会做类似的事情。

class BusinessRule < ActiveRecord::Base
  attr_accessor :skip_set_hierarchy

  before_action :set_hierarchy, unless: :skip_set_hierarchy

  ...
end

现在,如果您不希望触发回调,则可以根据需要将其设置为true:

def new_version
  business_rule = BusinessRule.new business_rule_params
  business_rule.skip_set_hierarchy = true
  business_rule.save
  #this can be refactored a lot (set the skip_set_hierarchy to true inside params, use create instead of new, I made it verbose on purpose to make it clearer)
end

ActiveRecord将跳过回调,因为skip_set_hierarchy将返回true。您无需更改其余代码,因为默认情况下它将返回nil

答案 1 :(得分:1)

我认为这是使用skip_callback方法的好例子:

.list-item

如果您经常要跳过/设置回调,则可以使用特殊的帮助方法将其简化:

BusinessRule.skip_callback(:create, :before, :set_hierarchy)

# your code to create BusinessRule objects without setting hierarchy
# ...

BusinessRule.set_callback(:create, :before, :set_hierarchy)

您将可以跳过这样的回调:

# config/initializers/without_callback.rb

module ActiveSupport::Callbacks::ClassMethods
  def without_callback(*args, &block)
    skip_callback(*args)
    yield
    set_callback(*args)
  end
end