From 3eb2ea20f2b5ecd493c1f67b7dde74ad63a3e03a Mon Sep 17 00:00:00 2001 From: Jon Distad Date: Fri, 3 Oct 2008 11:22:51 -0400 Subject: [PATCH] bang event methods now return false and dont transition on failed save --- lib/aasm.rb | 13 ++++++---- lib/persistence/active_record_persistence.rb | 9 ++++++- spec/unit/aasm_spec.rb | 25 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/lib/aasm.rb b/lib/aasm.rb index c182d00..c2c837d 100644 --- a/lib/aasm.rb +++ b/lib/aasm.rb @@ -97,10 +97,13 @@ module AASM private def aasm_current_state_with_persistence=(state) + save_success = true if self.respond_to?(:aasm_write_state) || self.private_methods.include?('aasm_write_state') - aasm_write_state(state) + save_success = aasm_write_state(state) end - self.aasm_current_state = state + self.aasm_current_state = state if save_success + + save_success end def aasm_current_state=(state) @@ -127,13 +130,13 @@ module AASM end if persist - self.aasm_current_state_with_persistence = new_state - self.send(self.class.aasm_events[name].success) if self.class.aasm_events[name].success + persist_successful = (self.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 - true + !persist && persist_successful else if self.respond_to?(:aasm_event_failed) self.aasm_event_failed(name) diff --git a/lib/persistence/active_record_persistence.rb b/lib/persistence/active_record_persistence.rb index 71d5b5e..39dc01e 100644 --- a/lib/persistence/active_record_persistence.rb +++ b/lib/persistence/active_record_persistence.rb @@ -188,8 +188,15 @@ module AASM # # NOTE: intended to be called from an event def aasm_write_state(state) + old_value = read_attribute(self.class.aasm_column) write_attribute(self.class.aasm_column, state.to_s) - self.save! + + unless self.save + write_attribute(self.class.aasm_column, old_value) + return false + end + + true end end diff --git a/spec/unit/aasm_spec.rb b/spec/unit/aasm_spec.rb index 33e9d9b..bc3533e 100644 --- a/spec/unit/aasm_spec.rb +++ b/spec/unit/aasm_spec.rb @@ -146,6 +146,31 @@ describe AASM, '- event firing with persistence' do foo.close! end + + it 'should return false if aasm_write_state is defined and returns false' do + foo = Foo.new + + def foo.aasm_write_state + false + end + + foo.should_receive(:aasm_write_state) + + foo.close!.should be_false + end + + it "should not update the aasm_current_state if the write fails" do + foo = Foo.new + + def foo.aasm_write_state + false + end + + foo.should_receive(:aasm_write_state) + + foo.close! + foo.aasm_current_state.should == :open + end end describe AASM, '- event firing without persistence' do