When changing a transition using event input as is done in the discard event method, it's possible to get into illegal state transitions when not halting the current transition in the right place. See the below example. This appears to be because when you call an event like keep! it resets @halted to false, so the after exit the halted workflow state transition is persisted. The workaround is to call halt after you call keep!, but it feels like the order there shouldn't affect things, and certainly that it shouldn't be possible to go from :trash to :fridge.
require 'workflow'
class Page
include Workflow
def workflow_state
@workflow_state
end
workflow do
state :new do
event :draw_on_page, :transitions_to => :drawing
end
state :drawing do
event :discard, :transitions_to => :trash
event :keep, :transitions_to => :fridge
end
state :trash
state :fridge
on_transition do |from, to, triggering_event, *event_args|
puts "#{workflow_state} -> #{to}"
end
end
def discard(good_drawing)
if good_drawing
halt
keep!
end
end
def keep
puts "so happy this drawing isn't going into the trash"
end
end
page = Page.new
page.draw_on_page!
page.discard!(true)
puts "Paper's final resting place: #{page.workflow_state}"
athorp$ bundle exec ruby repro.rb
-> drawing
so happy this drawing isn't going into the trash
drawing -> fridge
fridge -> trash
Paper's final resting place: trash
When changing a transition using event input as is done in the
discard
event method, it's possible to get into illegal state transitions when not halting the current transition in the right place. See the below example. This appears to be because when you call an event likekeep!
it resets@halted
tofalse
, so the afterexit
thehalt
ed workflow state transition is persisted. The workaround is to callhalt
after you callkeep!
, but it feels like the order there shouldn't affect things, and certainly that it shouldn't be possible to go from:trash
to:fridge
.