module Workflow::WorkflowInstanceMethods
Attributes
in_entry[RW]
in_exit[RW]
in_transition[RW]
Public Instance Methods
clear_transition_flags()
click to toggle source
# File lib/workflow.rb, line 236 def clear_transition_flags set_transition_flags nil, nil, nil end
current_state()
click to toggle source
# File lib/workflow.rb, line 188 def current_state loaded_state = load_workflow_state res = spec.states[loaded_state.to_sym] if loaded_state res || spec.initial_state end
halt(reason = nil)
click to toggle source
# File lib/workflow.rb, line 240 def halt(reason = nil) @halted_because = reason @halted = true end
halt!(reason = nil)
click to toggle source
# File lib/workflow.rb, line 245 def halt!(reason = nil) halt reason raise TransitionHalted.new(reason) end
halted?()
click to toggle source
See the 'Guards' section in the README @return true if the last transition was halted by one of the transition callbacks.
# File lib/workflow.rb, line 196 def halted? @halted end
halted_because()
click to toggle source
@return the reason of the last transition abort as set by the previous call of `halt` or `halt!` method.
# File lib/workflow.rb, line 202 def halted_because @halted_because end
process_event!(name, *args)
click to toggle source
# File lib/workflow.rb, line 206 def process_event!(name, *args) assure_transition_allowed! name event = current_state.events[name.to_sym] assure_target_state_exists!(event) set_transition_flags(current_state, spec.states[event.transitions_to], event) @halted_because = nil @halted = false return_value = run_action(event.action, *args) || run_action_callback(event.name, *args) if @halted run_on_failed_transition(*args) return_value = false else if event.perform_validation? and not valid? halt :validation_failed run_on_failed_transition(*args) @halted = true # make sure this one is not reset in the on_failed_transition callback return_value = false else transition(*args) end end return_value.nil? ? true : return_value end
set_transition_flags(current_state, target_state, event)
click to toggle source
# File lib/workflow.rb, line 230 def set_transition_flags(current_state, target_state, event) @in_exit = current_state @in_entry = target_state @in_transition = event end
spec()
click to toggle source
# File lib/workflow.rb, line 250 def spec # check the singleton class first class << self return workflow_spec if workflow_spec end c = self.class # using a simple loop instead of class_inheritable_accessor to avoid # dependency on Rails' ActiveSupport until c.workflow_spec || !(c.include? Workflow) c = c.superclass end c.workflow_spec end
Protected Instance Methods
assure_target_state_exists!(event)
click to toggle source
# File lib/workflow.rb, line 278 def assure_target_state_exists!(event) # Create a meaningful error message instead of # "undefined method `on_entry' for nil:NilClass" # Reported by Kyle Burton if !spec.states[event.transitions_to] raise WorkflowError.new \ "Event[#{event.name}]'s transitions_to[#{event.transitions_to}] is not a declared state." end end
assure_transition_allowed!(name)
click to toggle source
# File lib/workflow.rb, line 267 def assure_transition_allowed!(name) unless self.send "can_#{name}?" prohibit_transition! name end end
load_workflow_state()
click to toggle source
load_workflow_state
and persist_workflow_state
can be overriden to handle the persistence of the workflow state.
Default (non ActiveRecord) implementation stores the current state in a variable.
Default ActiveRecord implementation uses a 'workflow_state' database column.
# File lib/workflow.rb, line 362 def load_workflow_state @workflow_state if instance_variable_defined? :@workflow_state end
persist_workflow_state(new_value)
click to toggle source
# File lib/workflow.rb, line 366 def persist_workflow_state(new_value) @workflow_state = new_value end
prohibit_transition!(name)
click to toggle source
# File lib/workflow.rb, line 273 def prohibit_transition!(name) raise NoTransitionAllowed.new \ "There is no event #{name} defined for the #{current_state} state." end
run_action(action, *args)
click to toggle source
# File lib/workflow.rb, line 311 def run_action(action, *args) instance_exec(*args, &action) if action end
run_action_callback(action_name, *args)
click to toggle source
# File lib/workflow.rb, line 315 def run_action_callback(action_name, *args) self.send action_name.to_sym, *args if self.respond_to?(action_name.to_sym) end
run_on_entry(*args)
click to toggle source
# File lib/workflow.rb, line 319 def run_on_entry(*args) if self.wf_target_state.on_entry instance_exec(self.wf_prior_state.name, self.wf_event_name, *args, &self.wf_target_state.on_entry) else hook_name = "on_#{self.wf_target_state.name}_entry" self.send hook_name, self.wf_prior_state, self.wf_event_name, *args if self.respond_to? hook_name end end
run_on_exit(*args)
click to toggle source
# File lib/workflow.rb, line 328 def run_on_exit(*args) if self.wf_prior_state # no on_exit for entry into initial state if self.wf_prior_state.on_exit instance_exec(self.wf_target_state.name, self.wf_event_name, *args, &self.wf_prior_state.on_exit) else hook_name = "on_#{self.wf_prior_state.name}_exit" self.send hook_name, self.wf_target_state, self.wf_event_name, *args if self.respond_to? hook_name end end end
run_on_failed_transition(*args)
click to toggle source
# File lib/workflow.rb, line 301 def run_on_failed_transition(*args) if spec.on_failed_transition_proc return_value = instance_exec(self.wf_prior_state.name, self.wf_target_state.name, self.wf_event_name, *args, &spec.on_failed_transition_proc) else return_value = nil end clear_transition_flags return return_value end
run_on_transition(*args)
click to toggle source
# File lib/workflow.rb, line 297 def run_on_transition(*args) instance_exec(self.wf_prior_state.name, self.wf_target_state.name, self.wf_event_name, *args, &spec.on_transition_proc) if spec.on_transition_proc end
transition(*args)
click to toggle source
# File lib/workflow.rb, line 288 def transition(*args) run_on_exit(*args) run_on_transition(*args) val = persist_workflow_state wf_target_state.name run_on_entry(*args) clear_transition_flags val end
wf_event()
click to toggle source
# File lib/workflow.rb, line 351 def wf_event @in_transition end
wf_event_name()
click to toggle source
# File lib/workflow.rb, line 347 def wf_event_name @in_transition.name end
wf_prior_state()
click to toggle source
# File lib/workflow.rb, line 339 def wf_prior_state @in_exit end
wf_target_state()
click to toggle source
# File lib/workflow.rb, line 343 def wf_target_state @in_entry end