aasm/lib/aasm/instance_base.rb

77 lines
2.2 KiB
Ruby

module AASM
class InstanceBase
def initialize(instance)
@instance = instance
end
def current_state
@current_state ||= @instance.aasm_read_state
end
def current_state=(state)
@instance.aasm_write_state_without_persistence(state)
@current_state = state
end
def enter_initial_state
state_name = determine_state_name(@instance.class.aasm_initial_state)
state_object = state_object_for_name(state_name)
state_object.fire_callbacks(:before_enter, @instance)
state_object.fire_callbacks(:enter, @instance)
self.current_state = state_name
state_object.fire_callbacks(:after_enter, @instance)
state_name
end
def human_state
AASM::Localizer.new.human_state_name(@instance.class, current_state)
end
# QUESTION: shouldn't events and permissible_events be the same thing?
# QUESTION: shouldn't events return objects instead of strings?
def events(state=current_state)
events = @instance.class.aasm.events.values.select {|e| e.transitions_from_state?(state) }
events.map {|e| e.name}
end
# filters the results of events_for_current_state so that only those that
# are really currently possible (given transition guards) are shown.
# QUESTION: what about events.permissible ?
def permissible_events
events.select{ |e| @instance.send(("may_" + e.to_s + "?").to_sym) }
end
def state_object_for_name(name)
obj = @instance.class.aasm.states.find {|s| s == name}
raise AASM::UndefinedState, "State :#{name} doesn't exist" if obj.nil?
obj
end
def determine_state_name(state)
case state
when Symbol, String
state
when Proc
state.call(@instance)
else
raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc."
end
end
def may_fire_event?(name, *args)
event = @instance.class.aasm.events[name]
event.may_fire?(@instance, *args)
end
def set_current_state_with_persistence(state)
save_success = @instance.aasm_write_state(state)
self.current_state = state if save_success
save_success
end
end
end