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