module Wicked::Wizard::Validations::ClassMethods

Class methods on the included model

Public Instance Methods

all_wizard_steps() click to toggle source

@return [Array] a list of wizard steps for the class. Calls the method specified in the class instance attribute `wizard_steps_method`; returns an empty [Array] otherwise.

# File lib/wicked/wizard/validations.rb, line 23
def all_wizard_steps
  meth = self.wizard_steps_method
  if meth.present?
    case meth.class.to_s
      when "Symbol"
        self.send(meth)
      else
        raise ArgumentError, "wizard_steps_method accepts only a symbol, which should be a class method name"
    end
  else
    begin
      wizard_steps #if no wizard_steps_method set, assume `wizard_steps`.
    rescue
      []
    end
  end

end
previous_wizard_steps(step) click to toggle source

get previous steps for a given step @param step [Symbol] the name of the step you're on now @return [Array] the steps prior to this one

# File lib/wicked/wizard/validations.rb, line 45
def previous_wizard_steps(step)
  #cast the incoming step to a symbol
  step = step.to_sym if step.is_a?(String)
  self.all_wizard_steps.slice(0, self.all_wizard_steps.index(step)||0)
end
setup_validations!() click to toggle source

This is where the meat of the work happens. We call this in the class, and it iterates through all the wizard steps, calling `[wizard_step_name]_validations` on the class. If it responds, it should return a hash which can be passed straight into a `validates()` call

# File lib/wicked/wizard/validations.rb, line 54
def setup_validations!
  # Iterate through each step in the validations hash, and call a class method called [step]_step_validations
  # if it exists. For example, if step were called foo_details, the method would be called foo_details_validations
  self.all_wizard_steps.each do |step|
    validation_method_name = "#{step}_validations".to_sym
    if self.respond_to?(validation_method_name)
      #if the method responds, we're expecting a hash in the following format:
      # {
      #   field_name: {
      #     presence: true
      #   }
      # }
      self.send(validation_method_name).each do |field,validations|
        # validate the field, using the validations hash, but merge in a lambda which checks whether the object
        # is at the step yet, or not. If it's not, the validation isn't applied.
        validates field, validations.merge({if: ->{ self.current_and_previous_wizard_steps.include?(step)}})
      end
    end
  end
end