Practical eCommerce

 

Rails Acts_As_State_Machine Plugin

Author: Brian Getting
Publish Date: January 30, 2008
Blog: Developers' Corner
Tags: ruby, rails, plugin, Scott Barron

avatar

I realize that I haven't been posting as much recently, and one of the reasons is that we are getting down to the final build stages of our new website, which should be going live sometime in the next couple of months. Needless to say, and since I am basically the only one working on it, it has been taking up quite a bit of my time. On the plus side, there are lots of things to share. As I have mentioned before, our new site will be built using the Ruby on Rails framework, and I wanted to share my appreciation of Scott Barron's Acts_As_State_Machine plugin.

This plugin, which for a Rails application can be installed with one simple command, provides an engine for dealing with different "states" of a database record. If you are like me, that might be a little confusing. Basically what it means is that frequently you will have database records that will need to be assigned a certain state, or status. For example, let's say that you have user records in a database, and that you want to be able to assign certain"states" to users, such as active and suspended. In the past I have always tackled this with boolean fields in a database, or even an integer field where various numbers represent various states. A "1" might represent active, whereas a zero would represent inactive, and so on.

Enter this glorious plugin that let's you very simply define states for your records. In addition it, let's you define transitions from state to state, so that you can control how records move from state to state, and even trigger methods when a state change occurs. I'm finding that this functionality provides a very attractive alternative to using model observers, particularly with regard to sending notification emails and things like that.

In an effort to illustrate a simple example, take a look at this hypothetical example of an Article model, to which we would add the following code in order to set up draft and published states. Remember that a states string field needs to be added to the database table for the Article model:

acts_as_state_machine :initial => :draft 
state :passive 
state :draft,            :enter => :do_draft 
state :published,     :enter => :do_published

event :publish do 
    transitions :from => :draft, :to => :published 
end


event :suspend do 
    transitions :from => [:passive, :published], :to => :draft 
end

As you can see, we simply include the ActsAs_StateMachine methods, and then define the states that our record can transition between. In our case, we've just done a passive, draft and published state to keep things simple. The passive state never really happens, but is there as a default. As you can see, we actually tell the model that it's initial state (the state that is applied to it when it is created) should be draft. Also, we tell the model that when a record enters the draft state, it should run the method called do_draft, which is not shown here, but might do something like remove a publish date or send an email notification.

We then define a couple of events which we will be able to call on our model instances, and that outline the transitions that should occur when an event is triggered. For example, you see that our publish event moves a record from the draft state to the published state, which will trigger the do_published method to run as well. These events can be called on instances of the article model as shown below:

@article = Article.find_by_id(params[:id]) 
@article.publish!

When we define an event in our model, it creates a method with the same name and an exclamation point. So publish can be triggered by publish! in our controllers.

All in all, I have been loving this plugin. It has opened my eyes to how many times I have been using integers to represent states, and how nice it is to have a plugin engine that will provide the ability to manage state transitions in the model, rather than having them scattered all over my controller code. If you are reading this an within reach of Scott Barron, buy him a beer for me!

Add a Bookmark: Add 'Rails Acts_As_State_Machine Plugin' to Del.icio.us Digg 'Rails Acts_As_State_Machine Plugin' on Digg.com Submit 'Rails Acts_As_State_Machine Plugin' to reddit.com Blink 'Rails Acts_As_State_Machine Plugin' Add 'Rails Acts_As_State_Machine Plugin' to dzone Seed 'Rails Acts_As_State_Machine Plugin' on Newsvine Add 'Rails Acts_As_State_Machine Plugin' to Furl Add 'Rails Acts_As_State_Machine Plugin' to Spurl Add 'Rails Acts_As_State_Machine Plugin' on simpy.com Add 'Rails Acts_As_State_Machine Plugin' to fark.com BlogMark 'Rails Acts_As_State_Machine Plugin' Add 'Rails Acts_As_State_Machine Plugin' to Yahoo! myweb2 Add 'Rails Acts_As_State_Machine Plugin' to wists.com

0 Comments

Bloggers Wanted

We’re looking for merchants and other ecommerce professionals to share their experiences with our readers. If this interests you, we invite you to contact us.

Inside Practical eCommerce