ruby-on-railsbefore-filter

How to skip before filter in model with ruby on rails 5.2?


My application manages a hierarchy of documents. Each document has a hierarchycal index, which is calculated at creation only. File document.rb starts with

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

and the hierarchy is calculated based on parent and brothers so that self.hierarchy = last_one.next is evaluated in the scope of the parent.

Now, I add the version management feature. Thanks to a new_version method added to the controller, a document is duplicated using the @document.dup method, and then it is saved: the hierarchy is supposed to remain the same, and only the version number needs to be incremented.

Fine. But the before_create filter is triggered by the save action in the model, and the hierarchy is incremented, which does not fit the requirements.

How can I prevent the before filter in the model from triggering in the case of the new_version action in the controller?


Solution

  • I think this is the good case to use skip_callback method:

    BusinessRule.skip_callback(:create, :before, :set_hierarchy)
    
    # your code to create BusinessRule objects without setting hierarchy
    # ...
    
    BusinessRule.set_callback(:create, :before, :set_hierarchy)
    

    If you're going to skip/set callbacks quite often you could simplify it using special helping method:

    # config/initializers/without_callback.rb
    
    module ActiveSupport::Callbacks::ClassMethods
      def without_callback(*args, &block)
        skip_callback(*args)
        yield
        set_callback(*args)
      end
    end
    

    And you will be able to skip a callback like this:

    BusinessRule.without_callback(:create, :before, :set_hierarchy) do 
      # your code to create BusinessRule objects without setting hierarchy
      # ...
    end