mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
Allow multiple transitions in a single event with the same to and from states
As reported in https://github.com/aasm/aasm/issues/372 and https://github.com/aasm/aasm/issues/362, if two transitions in the same event have the same `to` and `from` states but differ in their guards, if any transition is valid, the first transition is the one that's always executed. This attempts to resolve that issue.
This commit is contained in:
parent
66d2a0de81
commit
6a924d6b1f
3 changed files with 44 additions and 3 deletions
|
@ -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
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
class MultipleTransitionsThatDifferOnlyByGuard
|
||||
include AASM
|
||||
|
||||
attr_accessor :executed_correctly
|
||||
|
||||
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_correctly = true
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
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
|
||||
end
|
Loading…
Reference in a new issue