From a9d9ca16c739ec39a192d29c62f760e51040fc6e Mon Sep 17 00:00:00 2001 From: rick Date: Sat, 28 Jun 2008 11:01:40 -0700 Subject: converted tests for more complex state transitions --- .../lib/active_model/state_machine/event.rb | 7 +++--- .../lib/active_model/state_machine/machine.rb | 26 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'activemodel/lib/active_model/state_machine') diff --git a/activemodel/lib/active_model/state_machine/event.rb b/activemodel/lib/active_model/state_machine/event.rb index cc7d563214..ea4df343de 100644 --- a/activemodel/lib/active_model/state_machine/event.rb +++ b/activemodel/lib/active_model/state_machine/event.rb @@ -3,9 +3,8 @@ module ActiveModel class Event attr_reader :name, :success - def initialize(name, options = {}, &block) - @name, @transitions = name, [] - machine = options.delete(:machine) + def initialize(machine, name, options = {}, &block) + @machine, @name, @transitions = machine, name, [] if machine machine.klass.send(:define_method, "#{name.to_s}!") do |*args| machine.fire_event(name, self, true, *args) @@ -19,7 +18,7 @@ module ActiveModel end def fire(obj, to_state = nil, *args) - transitions = @transitions.select { |t| t.from == obj.current_state } + transitions = @transitions.select { |t| t.from == obj.current_state(@machine ? @machine.name : nil) } raise InvalidTransition if transitions.size == 0 next_state = nil diff --git a/activemodel/lib/active_model/state_machine/machine.rb b/activemodel/lib/active_model/state_machine/machine.rb index 1da48290c5..53ce71794f 100644 --- a/activemodel/lib/active_model/state_machine/machine.rb +++ b/activemodel/lib/active_model/state_machine/machine.rb @@ -19,12 +19,21 @@ module ActiveModel self end - def fire_event(name, record, persist, *args) - state_index[record.current_state].call_action(:exit, record) - if new_state = @events[name].fire(record, *args) + def fire_event(event, record, persist, *args) + state_index[record.current_state(@name)].call_action(:exit, record) + if new_state = @events[event].fire(record, *args) state_index[new_state].call_action(:enter, record) + + if record.respond_to?(event_fired_callback) + record.send(event_fired_callback, record.current_state, new_state) + end + record.current_state(@name, new_state) else + if record.respond_to?(event_failed_callback) + record.send(event_failed_callback, event) + end + false end end @@ -37,13 +46,22 @@ module ActiveModel events = @events.values.select { |event| event.transitions_from_state?(state) } events.map! { |event| event.name } end + private def state(name, options = {}) @states << (state_index[name] ||= State.new(name, :machine => self)).update(options) end def event(name, options = {}, &block) - (@events[name] ||= Event.new(name, :machine => self)).update(options, &block) + (@events[name] ||= Event.new(self, name)).update(options, &block) + end + + def event_fired_callback + @event_fired_callback ||= (@name == :default ? '' : "#{@name}_") + 'event_fired' + end + + def event_failed_callback + @event_failed_callback ||= (@name == :default ? '' : "#{@name}_") + 'event_failed' end end end -- cgit v1.2.3