На мой взгляд, это не идеальное решение, но я понял, как выполнить свою задачу:
state_machine :initial => :new do
state :new
state :old
state :suspended
before_transition :to => :suspended, :do => :set_previous_state
state :unsuspended
after_transition :to => :unsuspended, :do => :restore_previous_state
event :suspend do
transition any - :suspended => :suspended
end
event :unsuspend do
transition :suspended => :unsuspended, :if => :previous_state_present?
end
end
private
def previous_state_present?
previous_state.present?
end
def set_previous_state
self.previous_state = state
end
def restore_previous_state
if previous_state
self.state = previous_state
self.previous_state = nil
end
end
Я начал с добавления в компьютер состояния "без приостановки".Хотя я никогда не хочу, чтобы что-то оставалось в этом состоянии, я не могу динамически сообщить state_machine, в какое состояние я хочу отменить приостановку.
Я добавил обратный вызов before_transition к событию suspend, чтобы сохранить состояние до его приостановки.
Я добавил обратный вызов after_transition к событию unsuspend, чтобы состояние немедленно обновлялось до предыдущего состояния, а это предыдущее состояние затем стиралось, чтобы предотвратить проблемы позже в жизни объекта.
Это не идеально.Это работает, но это намного сложнее, чем просто создавать события suspend и unsuspend в качестве автономных методов.Я не пошел по этому пути, потому что я хочу, чтобы state_machine контролировал все изменения состояния, а выход из него снимает защиту от перехода в / из недопустимых состояний, обратных вызовов и т. Д.