Class: StateMachine::TransitionCollection

Inherits:
Array
  • Object
show all
Includes:
Assertions
Defined in:
lib/state_machine/transition_collection.rb

Overview

Represents a collection of transitions in a state machine

Direct Known Subclasses

AttributeTransitionCollection

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Assertions

#assert_exclusive_keys, #assert_valid_keys

Constructor Details

#initialize(transitions = [], options = {}) ⇒ TransitionCollection

Creates a new collection of transitions that can be run in parallel. Each transition must be for a different attribute.

Configuration options:

  • :actions - Whether to run the action configured for each transition

  • :after - Whether to run after callbacks

  • :transaction - Whether to wrap transitions within a transaction

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/state_machine/transition_collection.rb', line 22

def initialize(transitions = [], options = {})
  super(transitions)
  
  # Determine the validity of the transitions as a whole
  @valid = all?
  reject! {|transition| !transition}
  
  attributes = map {|transition| transition.attribute}.uniq
  raise ArgumentError, 'Cannot perform multiple transitions in parallel for the same state machine attribute' if attributes.length != length
  
  assert_valid_keys(options, :actions, :after, :transaction)
  options = {:actions => true, :after => true, :transaction => true}.merge(options)
  @skip_actions = !options[:actions]
  @skip_after = !options[:after]
  @use_transaction = options[:transaction]
end

Instance Attribute Details

#skip_actionsObject (readonly)

Whether to skip running the action for each transition's machine



7
8
9
# File 'lib/state_machine/transition_collection.rb', line 7

def skip_actions
  @skip_actions
end

#skip_afterObject (readonly)

Whether to skip running the after callbacks



10
11
12
# File 'lib/state_machine/transition_collection.rb', line 10

def skip_after
  @skip_after
end

#use_transactionObject (readonly)

Whether transitions should wrapped around a transaction block



13
14
15
# File 'lib/state_machine/transition_collection.rb', line 13

def use_transaction
  @use_transaction
end

Instance Method Details

#perform(&block) ⇒ Object

Runs each of the collection's transitions in parallel.

All transitions will run through the following steps:

  1. Before callbacks

  2. Persist state

  3. Invoke action

  4. After callbacks (if configured)

  5. Rollback (if action is unsuccessful)

If a block is passed to this method, that block will be called instead of invoking each transition's action.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/state_machine/transition_collection.rb', line 50

def perform(&block)
  reset
  
  if valid?
    if use_event_attributes? && !block_given?
      each do |transition|
        transition.transient = true
        transition.machine.write(object, :event_transition, transition)
      end
      
      run_actions
    else
      within_transaction do
        catch(:halt) { run_callbacks(&block) }
        rollback unless success?
      end
    end
  end
  
  if actions.length == 1 && results.include?(actions.first)
    results[actions.first]
  else
    success?
  end
end