class RailsStateMachine::StateMachine
Attributes
model[R]
Public Class Methods
new(model, state_attribute)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 5 def initialize(model, state_attribute) @model = model @state_attribute = state_attribute @states_by_name = {} @events_by_name = {} build_model_module end
Public Instance Methods
configure(&block)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 13 def configure(&block) instance_eval(&block) define_state_methods define_state_constants register_initial_state define_event_methods define_model_methods end
event_names()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 36 def event_names @events_by_name.keys end
events()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 32 def events @events_by_name.values end
find_event(name)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 40 def find_event(name) @events_by_name.fetch(name.to_sym) end
has_state?(name)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 44 def has_state?(name) @states_by_name.key?(name.to_sym) end
state_names()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 28 def state_names @states_by_name.keys end
states()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 24 def states @states_by_name.values end
Private Instance Methods
build_model_module()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 65 def build_model_module # Using a state machine defines several methods on the model. # The model should be able to re-define them and `super` into the original method, if necessary. # For that, we use a module to store all methods. The module is loaded into the model class. @model_module = Module.new @model.include(@model_module) end
define_event_methods()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 107 def define_event_methods state_attribute = @state_attribute event_names.each do |event_name, event| model_module_eval do define_method "#{event_name}" do |**attributes| prepare_state_event_change(attributes.merge("#{state_attribute}_event": event_name)) save end define_method "#{event_name}!" do |**attributes| prepare_state_event_change(attributes.merge("#{state_attribute}_event": event_name)) save! end define_method "may_#{event_name}?" do state_machine_state_manager(state_attribute).transition_allowed_for?(event_name) end end end end
define_model_methods()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 128 def define_model_methods state_attribute = @state_attribute model_module_eval do define_method :"#{state_attribute}_event=" do |event_name| state_machine_state_manager(state_attribute).transition_to(event_name) end define_method :"#{state_attribute}_event" do state_machine_state_manager(state_attribute).next_event&.name end end end
define_state_constants()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 88 def define_state_constants state_names.each do |state_name| model_constant("STATE_#{state_name.upcase}", state_name) end end
define_state_methods()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 77 def define_state_methods state_attribute = @state_attribute state_names.each do |state_name| model_module_eval do define_method "#{state_name}?" do state_machine_state_manager(state_attribute).state == state_name.to_s end end end end
event(name, &block)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 54 def event(name, &block) event = Event.new(name, self) event.configure(&block) @events_by_name[name] = event end
model_constant(name, value)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 61 def model_constant(name, value) @model.const_set(name, value) end
model_module_eval(&block)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 73 def model_module_eval(&block) @model_module.module_eval(&block) end
register_initial_state()
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 94 def register_initial_state state_attribute = @state_attribute initial_state_name = states.detect(&:initial?)&.name return unless initial_state_name @model.after_initialize do manager = state_machine_state_manager(state_attribute) if new_record? && !manager.state manager.state = initial_state_name end end end
state(name, **options)
click to toggle source
# File lib/rails_state_machine/state_machine.rb, line 50 def state(name, **options) @states_by_name[name] = State.new(name, **options) end