Module: Statesmin::Machine

Defined in:
lib/statesmin/machine.rb

Overview

The main module, that should be ‘extend`ed in to state machine classes.

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#current_stateObject (readonly)

Returns the value of attribute current_state.



170
171
172
# File 'lib/statesmin/machine.rb', line 170

def current_state
  @current_state
end

Class Method Details

.included(base) ⇒ Object



9
10
11
12
# File 'lib/statesmin/machine.rb', line 9

def self.included(base)
  base.extend(ClassMethods)
  base.send(:attr_reader, :object)
end

.retry_conflicts(max_retries = 1) ⇒ Object

Retry any transitions that fail due to a TransitionConflictError



15
16
17
18
19
20
21
22
23
24
# File 'lib/statesmin/machine.rb', line 15

def self.retry_conflicts(max_retries = 1)
  retry_attempt = 0

  begin
    yield
  rescue TransitionConflictError
    retry_attempt += 1
    retry_attempt <= max_retries ? retry : raise
  end
end

Instance Method Details

#allowed_transitionsObject



188
189
190
191
192
# File 'lib/statesmin/machine.rb', line 188

def allowed_transitions
  successors_for(current_state).select do |state|
    can_transition_to?(state)
  end
end

#can_transition_to?(new_state, metadata = {}) ⇒ Boolean

Returns:

  • (Boolean)


194
195
196
197
198
199
200
201
# File 'lib/statesmin/machine.rb', line 194

def can_transition_to?(new_state,  = {})
  validate_transition(from: current_state,
                      to: new_state,
                      metadata: )
  true
rescue TransitionFailedError, GuardFailedError
  false
end

#execute(phase, initial_state, new_state, transition) ⇒ Object



217
218
219
220
# File 'lib/statesmin/machine.rb', line 217

def execute(phase, initial_state, new_state, transition)
  callbacks = callbacks_for(phase, from: initial_state, to: new_state)
  callbacks.each { |cb| cb.call(@object, transition) }
end

#in_state?(*states) ⇒ Boolean

Returns:

  • (Boolean)


184
185
186
# File 'lib/statesmin/machine.rb', line 184

def in_state?(*states)
  states.flatten.any? { |state| current_state == state.to_s }
end

#initialize(object, options = {}) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
# File 'lib/statesmin/machine.rb', line 172

def initialize(object, options = {})
  @object = object

  if (new_state = options[:state] && options[:state].to_s)
    self.class.validate_state(new_state)
    @current_state = new_state
  else
    @current_state = self.class.initial_state
  end
  send(:after_initialize) if respond_to? :after_initialize
end

#transition_to(new_state, metadata = {}, &block) ⇒ Object



222
223
224
225
226
# File 'lib/statesmin/machine.rb', line 222

def transition_to(new_state,  = {}, &block)
  self.transition_to!(new_state, , &block)
rescue TransitionFailedError, GuardFailedError
  false
end

#transition_to!(new_state, metadata = {}, &block) ⇒ Object



203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/statesmin/machine.rb', line 203

def transition_to!(new_state,  = {}, &block)
  initial_state = current_state
  new_state = new_state.to_s

  validate_transition(from: initial_state,
                      to: new_state,
                      metadata: )

  block_value = block.call(new_state, ) if block_given?
  @current_state = new_state

  block_value || true
end