module Stately::InstanceMethods

Public Class Methods

included(klass) click to toggle source

Sets up an object with Stately. The DSL is parsed and the Stately::Machine is initialized.

When an object is first initialized, Stately automatically sets the state attribute to the start state.

Additionally, a method is defined for each of the state's actions. These methods are used to transition between states. If you have a state named 'completed', Stately will infer the action to be 'complete' and define a method named 'complete'. You can then call 'complete' on the object to transition into the completed state.

# File lib/stately.rb, line 84
def InstanceMethods.included(klass)
  klass.class_eval do
    alias_method :init_instance, :initialize
    def initialize(*args)
      init_instance(*args)
      initialize_stately
    end

    stately_machine.states.each do |state|
      define_method(state.action) do
        transition_to(state)
      end

      define_method(:"#{state.name}?") do
        send(stately_machine.state_attr) == state.name.to_s
      end
    end
  end
end
new(*args) click to toggle source
# File lib/stately.rb, line 87
def initialize(*args)
  init_instance(*args)
  initialize_stately
end

Public Instance Methods

states() click to toggle source

@return [Array<String>] a list of state names.

# File lib/stately.rb, line 105
def states
  stately_machine.states.map(&:name)
end

Private Instance Methods

allowed_from_states(state) click to toggle source
# File lib/stately.rb, line 124
def allowed_from_states(state)
  if state.allow_from_states.empty?
    stately_machine.states.map(&:to_sym) - state.prevent_from_states
  else
    state.allow_from_states
  end
end
allowed_state_transition?(to_state) click to toggle source
# File lib/stately.rb, line 115
def allowed_state_transition?(to_state)
  if current_state == to_state.to_s
    raise InvalidTransition,
      "Prevented transition from #{current_state} to #{state.to_s}."
  end

  allowed_from_states(to_state).include?(current_state.to_sym)
end
current_state() click to toggle source
# File lib/stately.rb, line 132
def current_state
  (self.send(stately_machine.state_attr) || stately_machine.start).to_s
end
eligible_callback?(callback) click to toggle source
# File lib/stately.rb, line 136
def eligible_callback?(callback)
  if (callback.has_key?(:from) && callback[:from].to_s == current_state) ||
    (!callback.has_key?(:from))
    true
  else
    false
  end
end
initialize_stately() click to toggle source
# File lib/stately.rb, line 145
def initialize_stately
  set_initial_state
end
run_after_transition_callbacks(state) click to toggle source
# File lib/stately.rb, line 157
def run_after_transition_callbacks(state)
  state.after_transitions.each do |callback|
    self.send callback[:do]
  end
end
run_before_transition_callbacks(state) click to toggle source
# File lib/stately.rb, line 149
def run_before_transition_callbacks(state)
  state.before_transitions.each do |callback|
    if eligible_callback?(callback)
      self.send callback[:do]
    end
  end
end
set_initial_state() click to toggle source
# File lib/stately.rb, line 177
def set_initial_state
  write_model_attribute(stately_machine.state_attr, stately_machine.start.to_s)
end
state_named(state_name) click to toggle source
# File lib/stately.rb, line 163
def state_named(state_name)
  stately_machine.states.find { |s| s.to_s == state_name.to_s }
end
stately_machine() click to toggle source
# File lib/stately.rb, line 111
def stately_machine
  self.class.stately_machine
end
transition_to(state_name) click to toggle source
# File lib/stately.rb, line 167
def transition_to(state_name)
  state = state_named(state_name)

  if valid_transition_to?(state)
    run_before_transition_callbacks(state)
    write_model_attribute(stately_machine.state_attr, state.to_s)
    run_after_transition_callbacks(state)
  end
end
valid_transition_to?(state) click to toggle source
# File lib/stately.rb, line 185
def valid_transition_to?(state)
  if allowed_state_transition?(state)
    if state.validations.nil? || state.validations.empty?
      true
    else
      results = state.validations.collect do |validation|
        self.send validation
      end

      results.detect { |r| r == false }.nil?
    end
  else
    raise InvalidTransition,
      "Prevented transition from #{current_state} to #{state.to_s}."
  end
end
write_model_attribute(attr, val) click to toggle source
# File lib/stately.rb, line 181
def write_model_attribute(attr, val)
  send("#{attr}=", val)
end