Module: Workflow

Extended by:
ActiveSupport::Concern
Includes:
Callbacks, Errors
Defined in:
lib/workflow.rb,
lib/workflow/draw.rb,
lib/workflow/event.rb,
lib/workflow/state.rb,
lib/workflow/errors.rb,
lib/workflow/version.rb,
lib/workflow/callbacks.rb,
lib/workflow/configuration.rb,
lib/workflow/specification.rb,
lib/workflow/adapters/remodel.rb,
lib/workflow/callbacks/callback.rb,
lib/workflow/transition_context.rb,
lib/workflow/adapters/active_record.rb,
lib/workflow/adapters/active_record_validations.rb,
lib/workflow/callbacks/transition_callback_wrapper.rb

Overview

See also README.markdown for documentation

Defined Under Namespace

Modules: Adapter, Callbacks, ClassMethods, Draw, Errors Classes: Configuration, Event, Specification, State, TransitionContext

Constant Summary collapse

VERSION =
"1.4.1.3"

Constants included from Callbacks

Callbacks::CALLBACK_MAP

Instance Attribute Summary collapse

Attributes included from Callbacks

#transition_context

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#halted_becauseString (readonly)

Returns the reason given to a call to #halt or #halt!, if any.

Returns:

  • (String)

    The reason the transition was aborted.



62
63
64
# File 'lib/workflow.rb', line 62

def halted_because
  @halted_because
end

Class Method Details

.configObject



25
26
27
# File 'lib/workflow.rb', line 25

def self.config
  @@configuration ||= Configuration.new
end

.configure(&block) ⇒ Object



21
22
23
# File 'lib/workflow.rb', line 21

def self.configure(&block)
  block.call(config) if block_given?
end

Instance Method Details

#current_stateState

Returns a state object representing the current workflow state.

Returns:

  • (State)

    Current workflow state



48
49
50
51
52
# File 'lib/workflow.rb', line 48

def current_state
  loaded_state = load_workflow_state
  res = workflow_spec.states.find{|t| t.name==loaded_state.to_sym} if loaded_state
  res || workflow_spec.initial_state
end

#halt(reason = nil) ⇒ void

This method returns an undefined value.

Stop the current transition and set the reason for the abort.

Parameters:

  • optional (String)

    reason Reason for halting transition.



110
111
112
113
114
# File 'lib/workflow.rb', line 110

def halt(reason = nil)
  @halted_because = reason
  @halted = true
  throw :abort
end

#halt!(reason = nil) ⇒ void

This method returns an undefined value.

Sets halt reason and raises [TransitionHaltedError] error.

Parameters:

  • optional (String)

    reason Reason for halting

Raises:



120
121
122
123
124
# File 'lib/workflow.rb', line 120

def halt!(reason = nil)
  @halted_because = reason
  @halted = true
  raise TransitionHaltedError.new(reason)
end

#halted?Boolean

Deprecated. Check for false return value from #transition!

Returns:

  • (Boolean)

    true if the last transition was halted by one of the transition callbacks.



56
57
58
# File 'lib/workflow.rb', line 56

def halted?
  @halted
end

#transition!(name, *args, **attributes) ⇒ Type

Initiates state transition via the named event

Parameters:

  • name (Symbol)

    name of event to initiate

  • *args (Mixed)

    Arguments passed to state transition. Available also to callbacks

Returns:

  • (Type)

    description of returned object

Raises:



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/workflow.rb', line 69

def transition!(name, *args, **attributes)
  name = name.to_sym
  event = current_state.find_event(name)
  raise NoTransitionAllowed.new(
    "There is no event #{name} defined for the #{current_state.name} state") \
    if event.nil?

  @halted_because = nil
  @halted = false

  target = event.evaluate(self)
  unless target
    raise NoMatchingTransitionError.new("No matching transition found on #{name} for target #{target}.  Consider adding a catchall transition.")
  end

  from = current_state
  return_value = false
  begin
    @transition_context = TransitionContext.new \
      from: from.name,
      to: target.name,
      event: name,
      event_args: args,
      attributes: attributes,
      named_arguments: workflow_spec.named_arguments

    run_all_callbacks do
      callback_value  = run_action_callback name, *args
      persist_value   = persist_workflow_state(target.name)
      return_value    = callback_value || persist_value
    end
  ensure
    @transition_context = nil
  end
  return_value
end

#workflow_specSpecification

The specification for this object. Could be set on a singleton for the object, on the object's class, Or else on a superclass of the object.

Returns:

  • (Specification)

    The Specification that applies to this object.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/workflow.rb', line 130

def workflow_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