В state_machine, как установить следующее состояние на основе результата выполнения события?

Я использую гем state_machine Аарона Пфайфера в своем приложении Rails3 - он (все еще) отличный.

У меня есть событие, результат которого неизвестен до тех пор, пока оно не будет обработано, и я хотел бы установить следующее состояние на основе результата. Показанный здесь «очевидный» подход не работает: он вызывает ошибку ArgumentError: :picked_many is not a known state value.

Как правильно установить состояние на основе результата события? (Или я просто думаю об этом неправильно?)

class MyModel < ActiveRecord::Base 
  state_machine :initial => :top do 
    event :pickanumber do
      transition any => any
    end 
    state :picked_zero 
    state :picked_one 
    state :picked_many 
  end 
  def pickanumber(n) 
    self.state = case n 
                 when 0 then :picked_zero 
                 when 1 then :picked_one 
                 else :picked_many 
                 end 
    super
  end 
end 

и пример запуска:

> m = MyModel.create 
=> #<MyModel id: 26, state: "top", ...>
> m.pickanumber(2) 
ArgumentError: :picked_many is not a known state value

person fearless_fool    schedule 27.07.2011    source источник


Ответы (1)


Состояние внутренне хранится в виде строки, а не символа.

Это должно сработать...

def pickanumber(n)
    self.state = case n
                 when 0 then "picked_zero"
                 when 1 then "picked_one"
                 else "picked_many"
                 end
    super
end
person dexter    schedule 27.07.2011
comment
Почему строка, а не символ? Похоже, что конструкция Symbol была разработана для неизменяемой строковой метки. - person Damien Wilson; 28.07.2011
comment
Omygoshyouareright — версия @dexter работает. Я с @Damien - просто кажется странным, что state :picked_one работает с символом, а self.state = "picked_one" требует строки. Я позвоню автору... - person fearless_fool; 28.07.2011
comment
@fearless_fool: Страница API для библиотеки state_machine, кажется, снимает много тайн: rdoc .info/github/pluginaweek/state_machine/master/frames - person Damien Wilson; 28.07.2011
comment
@Damien: Согласен - документация отличная, но она не снимает тайну ОП! :) - person fearless_fool; 28.07.2011