Module: Wicked::Wizard::Validations::ClassMethods

Defined in:
lib/wicked/wizard/validations.rb

Overview

Class methods on the included model

Instance Method Summary collapse

Instance Method Details

#all_wizard_stepsArray

wizard_steps_method; returns an empty [Array] otherwise.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 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) ⇒ Array

get previous steps for a given step



45
46
47
48
49
# 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!Object

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



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 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