I remember the first time I learned about State Machines in my computer science classes. Actually, I don’t remember too many things about finite-state automa other than the fact that there were way too many mathematical models and UML diagrams in that class!
I’ve found state machines to be extremely useful and I’m surprised why I’ve never used them before (whether using an existing library or just writing one from scratch). Instead of keying off of objects, arrays, booleans or other data types/data structures to determine a certain action, we make use of states in our models. It makes things clean and consistent. In my PurchaseReturn model, for example, I could implement several states and transitions which clearly define before/after transitions along with their transition requirements
state_machine :initial => 'approved' do after_transition :to => 'received', :do => :process_receive after_transition :to => 'cancelled', :do => :process_canceled event :receive do transition :to => 'received', :from => 'approved', :if => :is_valid? end event :cancel do transition :to => 'cancelled', :from => 'approved' end end
As you can see in this example, it’s pretty simple to implement. You have ‘states’ as strings then ‘events’ which cause transitions from one state to another. In my example model, it initially gets created in the ‘approved’ state and based on certain events can either transition to ‘received’ or to ‘cancelled’. Then I invoke certain methods based on which state I transition to. I can also have conditional checks before making a transition (e.g. is_valid?).
Not all data models will greatly benefit from creating state machines. However, I think I’ll be making more use of them – particularly in the design phase of data modeling. If anything it helps you think of all the different states a model can be in. And if you can think in that respect, then I think you can avoid a lot of issues and bugs that will surface from bad design.