I’m trying to implement a “suspend” event that transitions the object to the :suspended state. But I need to be able to “unsuspend”, and return to the previous state. I added a previous_state field to the model, but I can’t see how to access it inside an event block.
This is the basic logic I’m trying to implement:
event :suspend do
owner.previous_state = self.state
transition [:new, :old] => :suspended
end
event :unsuspend do
transition :suspended => owner.previous_state.to_sym
owner.previous_state = nil
end
The state_machine docs haven’t been very helpful, and I can’t find examples online. Sometimes it’s tough to know how to describe something to google 🙂
This isn’t a perfect solution in my opinion, but I did figure out how to accomplish my task:
I started by adding an “unsuspended” state to my machine. While I never want something to stay in this state, I can’t dynamically tell state_machine what state I want to unsuspend to.
I added a before_transition callback to the suspend event, to save the state before it is suspended.
I added an after_transition callback to the unsuspend event, so the state is immediately updated to the previous state, and that previous state is then wiped out to prevent issues later in the object’s life.
This is not perfect. It works, but it’s a lot more complicated than just creating the suspend and unsuspend events as standalone methods. I didn’t go that route because I want state_machine controlling all state changes, and breaking out of that removes the protections against moving to/from invalid states, callbacks, etc.