module ::ScottBarron #:nodoc: module Acts #:nodoc: module StateMachine #:nodoc: module SupportingClasses class Event # Patching the fire method so that if you try to invoke an event on a record in a state # where the event is not available we throw an exception. Without this patch, invoking # say user.activate! on a user that is already active would do nothing and return an empty list. def fire(record) raise("Cannot invoke event #{name} on #{record.class.name}:#{record.id} since " + "it is not available in state #{record.current_state}") if next_states(record).blank? next_states(record).each do |transition| return true if transition.perform(record) end raise("Could not invoke event #{name} on #{record.class.name}:#{record.id} " + "in state #{record.current_state} - probably because a guard condition was not met") end end end module InstanceMethods # List events (transitions) available in the current state def current_events self.class.transition_table.keys.select do |event| self.class.transition_table[event].detect do |transition| transition.from == current_state end end end end end end end