diff --git a/lib/aasm/core/event.rb b/lib/aasm/core/event.rb index 3b1c8a5..889c4ca 100644 --- a/lib/aasm/core/event.rb +++ b/lib/aasm/core/event.rb @@ -128,12 +128,13 @@ module AASM::Core transitions.each do |transition| next if to_state and !Array(transition.to).include?(to_state) - if (options.key?(:may_fire) && Array(transition.to).include?(options[:may_fire])) || + if (options.key?(:may_fire) && transition.eql?(options[:may_fire])) || (!options.key?(:may_fire) && transition.allowed?(obj, *args)) - result = to_state || Array(transition.to).first + if options[:test_only] - # result = true + result = transition else + result = to_state || Array(transition.to).first Array(transition.to).each {|to| @valid_transitions[to] = transition } transition.execute(obj, *args) end diff --git a/spec/models/multiple_transitions_that_differ_only_by_guard.rb b/spec/models/multiple_transitions_that_differ_only_by_guard.rb new file mode 100644 index 0000000..159e9e7 --- /dev/null +++ b/spec/models/multiple_transitions_that_differ_only_by_guard.rb @@ -0,0 +1,31 @@ +class MultipleTransitionsThatDifferOnlyByGuard + include AASM + + attr_accessor :executed_second + + aasm do + state :start, :initial => true + state :gone + + event :go do + transitions :from => :start, :to => :gone, :guard => :returns_false, :after => :this_should_not_execute + transitions :from => :start, :to => :gone, :guard => :returns_true, :after => :this_should_execute + end + end + + def returns_false + false + end + + def returns_true + true + end + + def this_should_not_execute + raise RuntimeError, "This should not execute" + end + + def this_should_execute + self.executed_second = true + end +end \ No newline at end of file diff --git a/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb b/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb new file mode 100644 index 0000000..1f7477f --- /dev/null +++ b/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe "multiple transitions that differ only by guard" do + let(:job) { MultipleTransitionsThatDifferOnlyByGuard.new } + + it 'does not follow the first transition if its guard fails' do + expect{job.go}.not_to raise_error + end + + it 'executes the second transition\'s callbacks' do + job.go + expect(job.executed_second).to be_truthy + end +end