public
Description: Adds the ability to call events that change the state without writing to the database
Homepage: http://acts_as_state_machine_hacks.zilkey.com/
Clone URL: git://github.com/zilkey/acts_as_state_machine_hacks.git
Search Repo:
name age message
folder MIT-LICENSE Mon Apr 28 17:17:04 -0700 2008 first commit [zilkey]
folder README Mon Apr 28 17:19:14 -0700 2008 updated readme [zilkey]
folder Rakefile Mon Apr 28 17:17:04 -0700 2008 first commit [zilkey]
folder init.rb Mon Apr 28 17:17:04 -0700 2008 first commit [zilkey]
folder rdoc/ Mon Apr 28 17:19:14 -0700 2008 updated readme [zilkey]
folder test/ Mon Apr 28 17:17:04 -0700 2008 first commit [zilkey]
README
= Acts As State Machine Hacks

I dig acts_as_state_machine (http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/) and use it in 
almost all of my apps.  The biggest thing that bugged me was:

When you call a method like object.event! it writes to the database, instead of updating the current state, which makes 
it hard to set a state before validation.

== Installation

  script/plugin install http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/
  script/plugin install git://github.com/zilkey/acts_as_state_machine_hacks.git

== What this plugin does

This plugin hack adds new methods without the exclamation point - it just updates the attribute.  So if you have:

  class Conversation < ActiveRecord::Base
    acts_as_state_machine :initial => :open
    state :opened
    state :closed

    event :open do
      transitions :to => :opened,   :from => :closed
    end
  end

ActsAsStateMachine would give you:

  conversation.open!
  
That uses update_attribute under the hood.  This plugin adds:

  conversation.open
  
Which just sets state to opened, without touching the database.  Suitable for calling before you save, like:

  def create
    @conversation = Conversation.new(params[:conversation])
    @conversation.open if params[:conversation][:publish] == "open"
    if @conversation.save
      ...
    else
      ...
    end
  end

  def update
    @conversation = Conversation.find(params[:id])
    @conversation.open if params[:conversation][:publish] == "open"
    if @conversation.update_attributes(params[:conversation]) # => if this doesn't validate, the state column will not 
    have been written
      ...
    else
      ...
    end
  end

I wrote this primarily because I often change state based on fields in the model - like if you check a "published" check 
box that changes a state from pending to published.

This also allows the possibility of adding a dropdown list to an admin screen where admins can set the status, while 
maintaining the integrity by still relying on events.

== Requirements

You must have the acts_as_state_machine plugin installed and the acts_as_state_machine directory must be named 
"acts_as_state_machine".

== Warning

This copies methods directly from acts_as_state_machine.  If acts_as_state_machine is updated, this plugin hack will 
likely break.

== For developers

If you want to add your own hacks, you can fork this project on 
http://github.com/zilkey/acts_as_state_machine_hacks/tree/master

It includes working tests, which can be the hardest part of testing a plugin.