class Transitions::Machine

Attributes

auto_scopes[R]
events[RW]
initial_state[W]
klass[R]
state_index[RW]
states[RW]

Public Class Methods

new(klass, options = {}, &block) click to toggle source
# File lib/transitions/machine.rb, line 7
def initialize(klass, options = {}, &block)
  @klass = klass
  @states = []
  @state_index = {}
  @events = {}
  update(options, &block)
end

Public Instance Methods

current_state_variable() click to toggle source
# File lib/transitions/machine.rb, line 53
def current_state_variable
  # TODO: Refactor me away.
  :@current_state
end
events_for(state) click to toggle source
# File lib/transitions/machine.rb, line 48
def events_for(state)
  events = @events.values.select { |event| event.transitions_from_state?(state) }
  events.map!(&:name)
end
fire_event(event, record, persist, *args) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/transitions/machine.rb, line 30
def fire_event(event, record, persist, *args)
  handle_state_exit_callback record
  if new_state = transition_to_new_state(record, event, *args)
    handle_state_enter_callback record, new_state
    handle_event_fired_callback record, new_state, event
    record.update_current_state(new_state, persist)
    handle_event_success_callback record, event
    return true
  else
    handle_event_failed_callback record, event
    return false
  end
rescue => e
  raise e unless record.respond_to?(:event_failed)
  record.send(:event_failed, event)
  return false
end
initial_state() click to toggle source
# File lib/transitions/machine.rb, line 15
def initial_state
  @initial_state ||= (states.first ? states.first.name : nil)
end
update(options = {}, &block) click to toggle source
# File lib/transitions/machine.rb, line 19
def update(options = {}, &block)
  @initial_state = options[:initial] if options.key?(:initial)
  @auto_scopes = options[:auto_scopes]
  instance_eval(&block) if block
  include_scopes if @auto_scopes && ::Transitions.active_model_descendant?(klass)
  self
end

Private Instance Methods

event(name, options = {}, &block) click to toggle source
# File lib/transitions/machine.rb, line 94
def event(name, options = {}, &block)
  (@events[name] ||= Event.new(self, name)).update(options, &block)
end
handle_event_failed_callback(record, event) click to toggle source
# File lib/transitions/machine.rb, line 81
def handle_event_failed_callback(record, event)
  return unless record.respond_to?(:event_failed, true)
  record.send(:event_failed, event)
end
handle_event_fired_callback(record, new_state, event) click to toggle source
# File lib/transitions/machine.rb, line 72
def handle_event_fired_callback(record, new_state, event)
  return unless record.respond_to?(:event_fired, true)
  record.send(:event_fired, record.current_state, new_state, event)
end
handle_event_success_callback(record, event) click to toggle source
# File lib/transitions/machine.rb, line 77
def handle_event_success_callback(record, event)
  @events[event].success.call(record) if @events[event].success
end
handle_state_enter_callback(record, new_state) click to toggle source
# File lib/transitions/machine.rb, line 68
def handle_state_enter_callback(record, new_state)
  state_index[new_state].call_action(:enter, record)
end
handle_state_exit_callback(record) click to toggle source
# File lib/transitions/machine.rb, line 60
def handle_state_exit_callback(record)
  state_index[record.current_state].call_action(:exit, record)
end
include_scopes() click to toggle source

:reek: TooManyStatements: { max_statements: 7 }

# File lib/transitions/machine.rb, line 99
def include_scopes
  @states.each do |state|
    state_name = state.name.to_s
    if @klass.respond_to?(state_name)
      fail InvalidMethodOverride,
           "Transitions: Can not define scope `#{state_name}` because there is already"\
           'an equally named method defined - either rename the existing method or the state.'
    end
    scope = @klass.instance_exec { -> { where(state_machine.attribute_name => state_name) } }
    @klass.scope state_name, scope
  end
end
state(name, options = {}) click to toggle source
# File lib/transitions/machine.rb, line 86
def state(name, options = {})
  return if @state_index.key?(name) # Just ignore duplicates
  state = State.new(name, machine: self)
  state.update options
  @state_index[name] = state
  @states << state
end
transition_to_new_state(record, event, *args) click to toggle source
# File lib/transitions/machine.rb, line 64
def transition_to_new_state(record, event, *args)
  @events[event].fire(record, nil, *args)
end