geekq / workflow

Ruby finite-state-machine-inspired API for modeling workflow
MIT License
1.75k stars 207 forks source link

Same event, different transitions: Stack level too deep #162

Closed firedev closed 2 years ago

firedev commented 8 years ago

Here is what I have:

      workflow do
        state :working do
          event :next_state, transition_to: :not_working
        end

        state :not_working do
          event :next_state, transition_to: :vacation
        end

        state :vacation do
          event :next_state, transition_to: :sick
        end

        state :sick do
          event :next_state, transition_to: :working
        end
      end
    end

I just wanted to do next_state! all the time. But it causes these errors:

SystemStackError: stack level too deep
from workflow-1.2.0/lib/workflow/adapters/active_record.rb:12:in `load_workflow_state'
SystemStackError: stack level too deep
from activerecord-4.2.4/lib/active_record/attribute_methods/read.rb:85:in `read_attribute'

How do I do circular states?

Thanks.

firedev commented 8 years ago

In the end I just did it like this, but I wish it was structured differently so event checked state and then executed the corresponding transition:

class Day
  module WorkflowStates
    extend ActiveSupport::Concern

    included do
      NEXT_STATE = {
        'working' => 'not_working!',
        'not_working' => 'vacation!',
        'vacation' => 'sick!',
        'sick' => 'working!'
      }

      include ::Workflow

      workflow do
        state :working do
          event :not_working, transition_to: :not_working
        end

        state :not_working do
          event :vacation, transition_to: :vacation
        end

        state :vacation do
          event :sick, transition_to: :sick
        end

        state :sick do
          event :working, transition_to: :working
        end
      end
    end

    def next_state
      persisted? ? send(NEXT_STATE[workflow_state]) : save!
    end
  end
end
davidtolsma commented 8 years ago

@firedev Thanks for the example. It worked great for me.