Everyone should update to the new AASM plugin

by Mechaferret on November 27th, 2009

This post is dedicated to lavishing praise on something I had no hand in creating, but which I am very fond of right now: the new AASM update of the acts_as_state_machine plugin. It’s brilliant. Really. Everyone who uses acts_as_state_machine (which should be everyone who has a Rails app, because there’s no such thing as a web application without at least one object with complex, business-driven state rules) should go and update it to use AASM right now.

Some background: I’m writing code that needed to create an instance of NewModel for every existing instance of OldModel that was in one particular state (where OldModel implemented acts_as_state_machine). I check the code: sure enough, there are no named scopes to get only objects in that state. I could just write code to cover this case, but given how easy it should be to generate a named scope for each state, that seems like the wrong answer. Thus, I begin the following dialog:

Me: Does anyone know if acts_as_state_machine can generate named scopes for each state?
Other developer: No, I don’t think it does.
OD: That sure would be useful though.
M: And pretty easy to write…. But before I do that, let me check and see if anyone has updated it.
Other other developer: I made some modifications to acts_as_state_machine for that model, so that it could transition to multiple states.
M: (looking at the code in lib) Cool! It’s basically an implementation of a nondeterministic state machine.
OOD: I didn’t do it myself, I got it here. (IM’s me a link to http://justbarebones.blogspot.com/2007/11/actsasstatemachine-enhancements.html.)
M: Now I’m definitely looking to see what the latest acts_as_state_machine is.

To github I go, where I find AASM at http://github.com/rubyist/aasm/. Documentation is weak (I may try to contribute to that), but the code looks promising and has the multiple-state transitions OOD was using, as well as the ability to define specific actions on initial_state/final_state/transition triads. I download it, do a quick check to verify that it does in fact automatically generate named scopes for each state, and pop it in. A few syntax adjustments (everything is now prefixed with “aasm_”) and my new code works great.

Some of the old code, however, has started throwing errors. Why? Because it’s calling invalid state transitions! Apparently the old acts_as_state_machine just silently ignored them, while this one complains. Which is good, because now I can see that our mandatory email notifications weren’t getting generated sometimes, specifically in the cases in which the object was in an invalid state for the event that should generate them.

The new AASM allows transitions from a state to itself, and the aforementioned specific actions on initial_state/final_state/transition triads, though, so fixing the newly-discovered bug is as easy as defining a new transition and specific action. And now everything works, correctly, and AASM has helped me fix a bug I didn’t even know we had.

Summary of advantages of AASM over old acts_as_state_machine that I discovered in about half an hour of usage:

  1. AASM generates named scopes for each state.
  2. AASM allows nondeterministic transitions: that is, an object can transition from one state to a list of other states on an event, with the actual final state determined at runtime.
  3. AASM allows specification of actions on initial_state/final_state/transition triads.
  4. AASM actually throws errors on invalid state transitions, thus making debugging easier.

I’m sure there any many more, but that was more than enough to make my coding day much easier. And the actual code activity required to do the update is, as noted above, minimal.

I’m not sure if the authors think that the new version is completely ready for prime time. But in my experience it’s so much better than the old one (and also hasn’t displayed any bugginess), so I don’t think you need to wait.

From Technology

1 Comment
  1. David permalink

    You’re right about documentation being poor for aasm…I cannot find a way to define the behavior of a state machine *at runtime*, i.e. create a bare state machine object, then define its transitions and such. I have a system that has several different workflows, and could need more in the future, and so I hate to have to make future developers create new workflows in code, I’d rather have them be configurable at the application level.

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS