module FlowMachine::Workflow

Attributes

changes[RW]
options[RW]
previous_state[RW]
previous_state_persistence_callbacks[RW]

Public Class Methods

included(base) click to toggle source
# File lib/flow_machine/workflow.rb, line 10
def self.included(base)
  base.extend(ClassMethods)
  base.extend(ModelExtension)
  base.send(:attr_reader, :object)
end
new(object, options = {}) click to toggle source
# File lib/flow_machine/workflow.rb, line 105
def initialize(object, options = {})
  @object = object
  @options = options
  @previous_state_persistence_callbacks = []
end

Public Instance Methods

create?() click to toggle source

Useful for using in if/unless on state and after_save callbacks so you can run the callback only on the initial persistence

# File lib/flow_machine/workflow.rb, line 158
def create?
  changes[state_method.to_s].try(:first).blank?
end
current_state() click to toggle source
# File lib/flow_machine/workflow.rb, line 120
def current_state
  @current_state ||= self.class.states[current_state_name.to_sym].new(self)
end
current_state_name() click to toggle source
# File lib/flow_machine/workflow.rb, line 111
def current_state_name
  object.send(self.class.state_method)
end
Also aliased as: state
current_state_name=(new_state) click to toggle source
# File lib/flow_machine/workflow.rb, line 166
def current_state_name=(new_state)
  raise ArgumentError, "invalid state: #{new_state}" unless self.class.state_names.include?(new_state.to_s)

  object.send("#{self.class.state_method}=", new_state)
end
current_user() click to toggle source
# File lib/flow_machine/workflow.rb, line 172
def current_user
  options[:current_user]
end
persist() click to toggle source
# File lib/flow_machine/workflow.rb, line 137
def persist
  self.changes = object.changes
  # If the model has a default state from the database, then it doesn't get
  # included in `changes` when you're first saving it.
  changes[state_method.to_s] ||= [nil, current_state_name] if object.new_record?

  fire_callbacks(:before_save)
  current_state.fire_callbacks(:before_change, changes)

  if persist_object
    fire_state_callbacks
    fire_callbacks(:after_save)
    true
  else
    self.current_state_name = @previous_state.name.to_s if @previous_state
    false
  end
end
persist_object() click to toggle source
# File lib/flow_machine/workflow.rb, line 162
def persist_object
  object.save
end
previous_state_name() click to toggle source
# File lib/flow_machine/workflow.rb, line 116
def previous_state_name
  @previous_state.try(:name)
end
save() click to toggle source
# File lib/flow_machine/workflow.rb, line 133
def save
  persist
end
state()
Alias for: current_state_name
transition(options = {}) click to toggle source
# File lib/flow_machine/workflow.rb, line 124
def transition(options = {})
  @previous_state = current_state
  @current_state = nil
  self.current_state_name = options[:to].to_s if options[:to]
  @previous_state_persistence_callbacks << FlowMachine::StateCallback.new(options[:after]) if options[:after]
  fire_callbacks(:after_transition) unless previous_state == current_state
  current_state
end

Private Instance Methods

fire_callbacks(event) click to toggle source
# File lib/flow_machine/workflow.rb, line 178
def fire_callbacks(event)
  self.class.callbacks ||= {}
  self.class.callbacks[event].try(:each) do |callback|
    callback.call(self, changes)
  end
end
fire_state_callbacks() click to toggle source
# File lib/flow_machine/workflow.rb, line 185
def fire_state_callbacks
  previous_state.fire_callback_list(previous_state_persistence_callbacks) if previous_state
  @previous_state_persistence_callbacks = []
  current_state.fire_callbacks(:after_enter, changes) if changes.include? state_method.to_s
  current_state.fire_callbacks(:after_change, changes)
end
state_method() click to toggle source
# File lib/flow_machine/workflow.rb, line 192
def state_method
  self.class.state_method
end