Strange Symphonies The best way to predict the future is to invent it

Related tags

26Nov/090

Finder for Workflow States

Now a days for all my Finite State Machine needs on Ruby on Rails I use geekq's workflow. I find it much better to use than the previous popular Finite State Machine plugin on Rails, acts_as_state_machine.

named_scope

I need to locate all the models that are of a certain state, and thanks to named_scope. This can be done quite easily. Except when we have a lot of states I'd rather not write a named_scope for each individual state. For example:

class Order < ActiveRecord::Base
  named_scope :completed, :conditions => { :workflow_state => 'completed' }
end

It would be encumbersome to write this multiple times. I'd rather have a named_scope created for each state. This is my quick hack.

class Order < ActiveRecord::Base
  include Workflow
  workflow do
    state :new do
      ...
    end

    ...
  end

  (self.workflow_spec.states.keys - [:new]).each do |state|
    named_scope state, :conditions => { :workflow_state => state.to_s }
  end
end

After the workflow code you place you write:

  (self.workflow_spec.states.keys - [:new]).each do |state|
    named_scope state, :conditions => { :workflow_state => state.to_s }
  end

This iterates through each of our workflow states, and creates a named_scope for each one based on the name of the state. So you can easily do Order.completed and find all completed Orders.

Note: I had to remove :new (on line 12) from the array of keys as it would cause problems with my code. This is caused from overwriting the new method. You can solve this by probably putting a prefix for the named_scope name.

I know it can be extracted to use alias_method_chain and modify the Workflow sourcecode, but I enjoy my hack.