workflow icon indicating copy to clipboard operation
workflow copied to clipboard

Illegal state transitions

Open aThorp96 opened this issue 1 year ago • 0 comments

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

aThorp96 avatar Mar 05 '24 01:03 aThorp96