Class: StateMachines::TransitionCollection

Inherits:
Array
  • Object
show all
Defined in:
lib/state_machines/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

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



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

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
  fail ArgumentError, 'Cannot perform multiple transitions in parallel for the same state machine attribute' if attributes.length != length

  options.assert_valid_keys(:actions, :after, :use_transactions)
  options = {actions: true, after: true, use_transactions: true}.merge(options)
  @skip_actions = !options[:actions]
  @skip_after = !options[:after]
  @use_transactions = options[:use_transactions]
end

Instance Attribute Details

#skip_actionsObject (readonly)

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



6
7
8
# File 'lib/state_machines/transition_collection.rb', line 6

def skip_actions
  @skip_actions
end

#skip_afterObject (readonly)

Whether to skip running the after callbacks



9
10
11
# File 'lib/state_machines/transition_collection.rb', line 9

def skip_after
  @skip_after
end

#use_transactionsObject (readonly)

Whether transitions should wrapped around a transaction block



12
13
14
# File 'lib/state_machines/transition_collection.rb', line 12

def use_transactions
  @use_transactions
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.



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

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