module StatefulController

Constants

VERSION

Public Class Methods

aasm(*args, &block) click to toggle source
# File lib/stateful_controller.rb, line 26
def aasm(*args, &block)
  ret = aasm_orig(*args, &block)  # first process the state machine DSL normally
  if block
    # then this is a DSL call, so remove the event methods it normally makes on the the object.
    methods_to_remove = aasm.events.map(&:name)
    methods_to_remove.each {|method|
      remove_method(method)
    }
 end
  ret
end
Also aliased as: aasm_orig
aasm_orig(*args, &block)
Alias for: aasm
new() click to toggle source
Calls superclass method
# File lib/stateful_controller.rb, line 58
def initialize
  super
end

Public Instance Methods

next() click to toggle source

StatefulController always defines a special action called 'next' that goes to the next available transition.

# File lib/stateful_controller.rb, line 41
def next
  # this may rely on events having exactly one transition... otherwise, we may need an argument? (TBD)
  next_events = aasm.events(permitted: true).map(&:name)
  __debug("choosing first from next events: #{next_events.inspect}")
  next_event = next_events.first
  __process(next_event)
  self.send(next_event)
end
start() click to toggle source

SC also has a special action called “start” which clears state and reloads it (defaulting back to the initial state)

# File lib/stateful_controller.rb, line 51
def start
  save_state(nil)
  __load
end

Protected Instance Methods

__debug(msg) click to toggle source
# File lib/stateful_controller.rb, line 121
def __debug(msg)
  Rails.logger.debug("DEBUG [StatefulController]: #{msg}")
end
__finish() click to toggle source
# File lib/stateful_controller.rb, line 107
def __finish
  state.current_state = aasm.current_state
  __debug("calling save_state with #{state.inspect}")
  save_state(state)
end
__load() click to toggle source
# File lib/stateful_controller.rb, line 79
def __load
  @state = load_state
  __debug("load_state returned #{@state.inspect}")
  raise ArgumentError, "load_state() must return a StatefulController::State or subclass." unless @state.kind_of?(State)

  # allow the StatefulController to retain it's current state across requests (since controller instances are created per request in Rails)
  if state.current_state.nil?
    state.current_state = aasm.current_state  # if load_state didn't recover a current_state, then use the aasm initial.
  else
    aasm.current_state = state.current_state  # otherwise, set the aasm.current_state to the loaded current_state.
  end
end
__load_and_process() click to toggle source

before filter for setup

# File lib/stateful_controller.rb, line 67
def __load_and_process
  __load

  # rails action should always be something convertible to a symbol
  event = params[:action].to_sym

  # next is a special action, don't try to send the event.
  return if event == :next

  __process(event)
end
__process(event) click to toggle source
# File lib/stateful_controller.rb, line 92
def __process(event)
  # manually trigger the event (while we consider the aasm events as "actions", we reserve the methods in the
  # controller as actual actions instead of aasm event triggering sugar.)
  # adapted from ./lib/aasm/base.rb:85

  # while the aasm gem supports multiple state machines per class, StatefulController always uses only one state machine, the default.
  # so we may substitute :default for @name in the DSL impl:
  # original line:  aasm(:#{@name}).current_event = :#{name}
  aasm.current_event = event

  # also, aasm supports arguments for events, but because StatefulController models Rails controller actions, no arguments or blocks are supported.
  # original line:  aasm_fire_event(:#{@name}, :#{name}, {:persist => false}, *args, &block)
  aasm_fire_event(:default, event, {persist: false}, [])
end
default_render(*args) click to toggle source
# File lib/stateful_controller.rb, line 62
def default_render(*args)
  render aasm.current_state
end
load_state() click to toggle source
# File lib/stateful_controller.rb, line 113
def load_state
  raise NotImplementedError, "Controllers that include StatefulController should define the load_state() method."
end
save_state() click to toggle source
# File lib/stateful_controller.rb, line 117
def save_state
  raise NotImplementedError, "Controllers that include StatefulController should define the save_state() method."
end