We have a Ruby on Rails application.
We're using Ruby's aasm gem to manage states of objects.
has_state
aasm do
state :created, :initial => true
state :submitted
state :rejected
state :approved
event :submit do
transitions :to => :submitted, :from => [:created]
end
event :mark_as_incomplete do
transitions :to => :created, :from => [:submitted]
end
event :approve do
transitions :to => :approved, :from => [:submitted]
end
event :reject do
transitions :to => :rejected, :from => [:submitted]
end
end
If we know an object's current state, which can be obtained using
object.aasm_current_state
and we also know the state to transition to, how can we invoke the event?
Please note, the from-state and to-state are variables, so we need to do the above dynamically. Of course, with certain to-state and from-state combination, the transition isn't available, in that case we should detect an error.
We're also assuming between any two state combination (to-state and from-state), there's only 1 event, I think theoretically there can be more than 1.
I think this can be achieved by delving into the innards of aasm source code, which, arguably, may not be a good practice. Any thoughts?
Just wonder if anyone has done this before.
Thanks!
There is no way provided by AASM to do this, but your own answer is getting already close enough to where you want to go. AASM is built around the assumption, that state machines allow multiple different transitions from one state to another.
If the event name is not relevant for you, you could reuse the to-state name as event name, like this:
aasm do
...
event :approved do
transitions :from => :submitted, :to => :approved
end
...
end
By this you can fire the event by just knowing the to-state name
approval_request.send(to_state)
By default, AASM raises an exception if this transition is not allowed. If you don't like the exception, set whiny_transitions
to false
, like this:
aasm :whiny_transitions => false do
...
end