Существуют ли конечные автоматы Ruby / Rails, которые выполняют переходы событий при изменении состояния? - PullRequest
2 голосов
/ 01 января 2011

Надеюсь, это не глупый вопрос, и я просто не пропускаю что-то в машинах состояний Ruby / Rails (AASM, Transitions, AlterEgo и т. Д.).

Из того, что я могу сказать, эти реализации конечного автомата оперируют предисловием, что событие будет запущено, и соответствующий переход для этого события будет инициирован на основе старого и нового состояния.Тем не менее, они, кажется, не работают по-другому;скажем, пользователь хочет изменить состояние с «созданного» на «назначенный» и иметь правильный переход, а не запускать событие, которое вызывает переход текущего состояния в новое состояние.

По сути, я хочупользователь должен иметь возможность выбрать новое состояние из поля выбора доступных состояний и выполнить соответствующие переходы, средства защиты, обратные вызовы и т. д.

Кто-нибудь знает, поддерживают ли существующие реализации конечного автомата это?

Ответы [ 2 ]

2 голосов
/ 01 января 2011

Конечные автоматы по своей природе не позволяют произвольно переходить к любому состоянию в системе. У каждого есть точка входа, и каждый раз, когда вы хотите изменить состояние, оцениваются некоторые условия (одно из которых может быть событием ввода), и следующее состояние является результатом этих условий. Однако у вас может быть конечный автомат с переходами, определенными из каждого состояния в другое.

class Ticket
  acts_as_state_machine :initial => :new

  state :new
  state :open
  state :resolved

  event :open do
    transitions :to => :open, 
      :from => [:new, :resolved], :guard => :can_be_open?
  end

  event :new do
    transitions :to => :new, 
      :from => [:open, :resolved], :guard => :can_be_new?
  end

  event :resolved do
    transitions :to => :resolved,
      :from => [:open, :new], :guard => :can_be_resolved?
  end

  private

  def can_be_resolved?
    !resolution.blank?
  end

  ...

end

@ticket = Ticket.create
@ticket.state # => new
@ticket.resolved!
@ticket.state # => resolved

Итак, вам нужно проверить желаемое состояние из выпадающего списка и вызвать соответствующий переход в результате. Вы можете использовать что-то простое, например attr_accessor :new_state, а затем new_state => event оператор отображения или case, который ваша модель вызывает before_validation.

0 голосов
/ 30 января 2011

Вы можете выполнить то, что вы пытаетесь сделать с моим драгоценным камнем flojo.Просто назовите события после состояний и сделайте так, чтобы эти события инициировали переход из подстановочного состояния в состояние, выбранное в раскрывающемся списке.

Если в раскрывающемся списке имеется состояние «в ожидании», вы можете настроить событие flojoиспользуя следующий фрагмент

event :pending do
  # :any is a wildcard state and is only valid as a begin state.
  transition :any, :pending
end

После того, как ваша форма отправлена, вам нужно будет поставить префикс «в ожидании» с «wf_», преобразовать его в символ и затем отправить его вашему объекту.Было бы чище просто создать в вашем классе метод, который выполняет префикс и преобразование символов, а затем делегировать для отправки.

your_object.send :wf_pending

https://github.com/alternegro/flojo

...