5

I am looking for a relatively simple state machine plugin for a Rails 3 / Active Record project.

I've done a little research and come up with the following plugins:

But they all seem very similar, so I am curious to know if anyone has had real-world experience with any of them.

Thanks!

Jeremy Lynch
  • 6,780
  • 3
  • 52
  • 63
Adam Albrecht
  • 6,680
  • 4
  • 31
  • 35
  • If it helps to get an idea of their relative popularity, you can look here: https://www.ruby-toolbox.com/categories/state_machines – Nathan Long Aug 15 '12 at 16:01
  • Comment: We've created [a short video](http://www.platform45.com/videos/show/10) explaining stateflow which may help. – Neil Sep 14 '11 at 19:19

6 Answers6

12

state_machine seems to be the one people say to use, at least who I've spoken to. It is environment agnostic, so you don't have to use one state machine in one part of your app, and a completely different one in another part of your app.

Update February 2015

State Machine is unfortunately no longer maintained and there are many issues, which makes it a less favourable choice. However, this fork of the project is actively maintained and appears to be stable.

Jeremy Lynch
  • 6,780
  • 3
  • 52
  • 63
d11wtq
  • 34,788
  • 19
  • 120
  • 195
4

I ended up using stateflow and like it. https://github.com/ryanza/stateflow

It runs with rails 3.0, and it is similar in approach to the state machine code that was in several of the rails 3.0 betas but dropped from the final release. I've not followed along to see what the current thinking about having a state machine inside rails is - but I guess that if a state machine gets reintegrated in a future release it will be a bit like this. Hopefully that will mean minimal code changes if I ever want to drop the gem and use core functionality

chrispanda
  • 3,204
  • 1
  • 21
  • 23
  • I hadn't heard of this one - I really like the syntax. I just added it to the list above. – Adam Albrecht Jun 27 '11 at 16:59
  • Stateflow has the benefit of dynamic transitions (where you can have some business logic determine the next state), in case that is something you need. – crishoj Aug 10 '12 at 08:06
3

I would approach Transitions with care. The author/extractor says he doesn't have time to maintain it, and usually favors state_machine on his new projects.

On the other hand, it does work (although check the open issues to see if it will work in your case). I'm using Transitions myself on a project, but for a trivial state machine.

I've used acts as state machine before, on a Rails 2 project, and it did really well (even with very complex state machines)

RyanWilcox
  • 13,890
  • 1
  • 36
  • 60
2

SimpleStateMachine is a simple DSL to decorate existing methods with state transition guards.

class LampSwitch
   extend SimpleStateMachine

   def initialize
     self.state = 'off'
   end

   event :push_switch, :off => :on
end

lamp = LampSwitch.new
lamp.state          # => 'off'
lamp.off?           # => true
lamp.push_switch    #
lamp.state          # => 'on'
lamp.on?            # => true

It works with ActiveModel validations and allows events to be called with arguments:

class User < ActiveRecord::Base
  ...
  def activate_account(activation_code)
    if activation_code_invalid?(activation_code)
      errors.add(:activation_code, 'Invalid')
    end
  end
  event :activate_account, :invited => :activated
end

user = User.new
user.activate_account!('INVALID') # => raises ActiveRecord::RecordInvalid
user.activated?                     # => false
user.activate_account!('VALID')
user.activated?                     # => true

It can rescue exception:

def download_data
  raise Service::ConnectionError
end
event :download_data, Service::ConnectionError => :download_failed

user.download_data               # catches Service::ConnectionError
user.state                       # => "download_failed"
user.state_machine.raised_error  # the raised error
Petrik de Heus
  • 970
  • 6
  • 9
0

I would recommend Workflow as i feel its the easiest of all the state machines available .

Sudhir Vishwakarma
  • 785
  • 10
  • 15
0

Even the simplest state machine gems had way more features than I needed, so I just decided to roll my own solution. I tried Transitions and Stateflow, but had minor issues with both.

Adam Albrecht
  • 6,680
  • 4
  • 31
  • 35
  • It is slightly interesting to know what you chose, but I'm not sure this qualifies as an answer. Why not just make it an update to your question? – iconoclast Jul 30 '13 at 15:38
  • Good point. I'll leave it as an answer, but un-mark it as "the" answer since it's really an open-ended question. – Adam Albrecht Jul 31 '13 at 13:58
  • To really qualify as an answer, don't you think you should share the code you used? Otherwise this Q & A is of the form "How should I do X?" "I did X my own way". – iconoclast Jul 31 '13 at 14:16