diff --git a/lib/aasm.rb b/lib/aasm.rb index c2c837d..804f2e1 100644 --- a/lib/aasm.rb +++ b/lib/aasm.rb @@ -96,7 +96,7 @@ module AASM end private - def aasm_current_state_with_persistence=(state) + def set_aasm_current_state_with_persistence(state) save_success = true if self.respond_to?(:aasm_write_state) || self.private_methods.include?('aasm_write_state') save_success = aasm_write_state(state) @@ -125,18 +125,21 @@ module AASM unless new_state.nil? aasm_state_object_for_state(new_state).call_action(:enter, self) - if self.respond_to?(:aasm_event_fired) - self.aasm_event_fired(self.aasm_current_state, new_state) - end - + persist_successful = true if persist - persist_successful = (self.aasm_current_state_with_persistence = new_state) + persist_successful = set_aasm_current_state_with_persistence(new_state) self.send(self.class.aasm_events[name].success) if persist_successful && self.class.aasm_events[name].success else self.aasm_current_state = new_state end - !persist && persist_successful + if persist_successful + self.aasm_event_fired(self.aasm_current_state, new_state) if self.respond_to?(:aasm_event_fired) + else + self.aasm_event_failed(name) if self.respond_to?(:aasm_event_failed) + end + + persist_successful else if self.respond_to?(:aasm_event_failed) self.aasm_event_failed(name) diff --git a/spec/unit/aasm_spec.rb b/spec/unit/aasm_spec.rb index bc3533e..886f50b 100644 --- a/spec/unit/aasm_spec.rb +++ b/spec/unit/aasm_spec.rb @@ -150,12 +150,10 @@ describe AASM, '- event firing with persistence' do it 'should return false if aasm_write_state is defined and returns false' do foo = Foo.new - def foo.aasm_write_state + def foo.aasm_write_state(state) false end - foo.should_receive(:aasm_write_state) - foo.close!.should be_false end @@ -238,7 +236,29 @@ describe AASM, '- event callbacks' do foo.close! end - it 'should call aasm_event_fired if defined and successful for non-bang fire' do + it 'should not call aasm_event_fired if defined but persist fails for bang fire' do + foo = Foo.new + def foo.aasm_event_fired(from, to) + end + foo.stub!(:set_aasm_current_state_with_persistence).and_return(false) + + foo.should_not_receive(:aasm_event_fired) + + foo.close! + end + + it 'should not call aasm_event_failed if defined and persist fails for bang fire' do + foo = Foo.new + def foo.aasm_event_failed(from, to) + end + foo.stub!(:set_aasm_current_state_with_persistence).and_return(false) + + foo.should_receive(:aasm_event_failed) + + foo.close! + end + + it 'should call aasm_event_fired if defined and successful for non-bang fire' do foo = Foo.new def foo.aasm_event_fired(from, to) end