Add two event callbacks:

aasm_event_fired(from, to) - called when an event is fired successfully
aasm_event_failed(event)   - called when an event fails

These could be used to implement transition logging [Artem Vasiliev] or
setting a timestamp column [Mike Ferrier] as well as other pieces of love and magic.
This commit is contained in:
Scott Barron 2008-03-02 07:52:46 -05:00
parent 29304c70ae
commit 61b6b8ec06
4 changed files with 43 additions and 2 deletions

View File

@ -1,3 +1,6 @@
* Add some event callbacks, #aasm_event_fired(from, to), and #aasm_event_failed(event)
Based on transition logging suggestion [Artem Vasiliev] and timestamp column suggestion [Mike Ferrier]
* Add #aasm_events_for_state and #aasm_events_for_current_state [Joao Paulo Lins]
* Ensure that a state is written for a new record even if aasm_current_state or

2
TODO
View File

@ -9,5 +9,3 @@ Cool ideas from users:
* Support multiple state machines on one object (Chris Nelson)
* http://justbarebones.blogspot.com/2007/11/actsasstatemachine-enhancements.html (Chetan Patil)
* transition logging (Artem Vasiliev)
* timestamp column for state change on AR (Mike Ferrier)

View File

@ -41,9 +41,17 @@ module AASM
define_method("#{name.to_s}!") do
new_state = self.class.aasm_events[name].fire(self)
unless new_state.nil?
if self.respond_to?(:aasm_event_fired)
self.aasm_event_fired(self.aasm_current_state, new_state)
end
self.aasm_current_state = new_state
true
else
if self.respond_to?(:aasm_event_failed)
self.aasm_event_failed(name)
end
false
end
end

View File

@ -9,6 +9,14 @@ class Foo
aasm_event :close do
transitions :to => :closed, :from => [:open]
end
aasm_event :null do
transitions :to => :closed, :from => [:open], :guard => :always_false
end
def always_false
false
end
end
class Bar
@ -122,3 +130,27 @@ describe AASM, '- getting events for a state' do
foo.aasm_events_for_current_state
end
end
describe AASM, '- event callbacks' do
it 'should call aasm_event_fired if defined and successful' do
foo = Foo.new
def foo.aasm_event_fired(from, to)
end
foo.should_receive(:aasm_event_fired)
foo.close!
end
it 'should call aasm_event_failed if defined and transition failed' do
foo = Foo.new
def foo.aasm_event_failed(event)
end
foo.should_receive(:aasm_event_failed)
foo.null!
end
end