state_machine

https://github.com/pluginaweek/state_machine

Ruby

Adds support for creating state machines for attributes on any Ruby class

StateMachine::InstanceMethods#fire_events

Runs one or more events in parallel.  All events will run through the
following steps:
* Before callbacks
* Persist state
* Invoke action
* After callbacks

For example, if two events (for state machines A and B) are run in
parallel, the order in which steps are run is:
* A - Before transition callbacks
* B - Before transition callbacks
* A - Persist new state
* B - Persist new state
* A - Invoke action
* B - Invoke action (only if different than A's action)
* A - After transition callbacks
* B - After transition callbacks

*Note* that multiple events on the same state machine / attribute cannot
be run in parallel.  If this is attempted, an ArgumentError will be
raised.

== Halting callbacks

When running multiple events in parallel, special consideration should
be taken with regard to how halting within callbacks affects the flow.

For *before* callbacks, any <tt>:halt</tt> error that's thrown will
immediately cancel the perform for all transitions.  As a result, it's
possible for one event's transition to affect the continuation of
another.

On the other hand, any <tt>:halt</tt> error that's thrown within an
*after* callback with only affect that event's transition.  Other
transitions will continue to run their own callbacks.

== Example

  class Vehicle
    state_machine :initial => :parked do
      event :ignite do
        transition :parked => :idling
      end
      
      event :park do
        transition :idling => :parked
      end
    end
    
    state_machine :alarm_state, :namespace => 'alarm', :initial => :on do
      event :enable do
        transition all => :active
      end
      
      event :disable do
        transition all => :off
      end
    end
  end
  
  vehicle = Vehicle.new                         # => #<Vehicle:0xb7c02850 @state="parked", @alarm_state="active">
  vehicle.state                                 # => "parked"
  vehicle.alarm_state                           # => "active"
  
  vehicle.fire_events(:ignite, :disable_alarm)  # => true
  vehicle.state                                 # => "idling"
  vehicle.alarm_state                           # => "off"
  
  # If any event fails, the entire event chain fails
  vehicle.fire_events(:ignite, :enable_alarm)   # => false
  vehicle.state                                 # => "idling"
  vehicle.alarm_state                           # => "off"
  
  # Exception raised on invalid event
  vehicle.fire_events(:park, :invalid)          # => StateMachine::InvalidEvent: :invalid is an unknown event
  vehicle.state                                 # => "idling"
  vehicle.alarm_state                           # => "off"

Source | Google | Stack overflow

Edit

git clone [email protected]:pluginaweek/state_machine.git

cd state_machine

open lib/state_machine/extensions.rb

Contribute

# Make a new branch

git checkout -b -your-name--update-docs-StateMachine--InstanceMethods-fire_events-for-pr


# Commit to git

git add lib/state_machine/extensions.rbgit commit -m "better docs for StateMachine::InstanceMethods#fire_events"


# Open pull request

gem install hub # on a mac you can `brew install hub`

hub fork

git push <your name> -your-name--update-docs-StateMachine--InstanceMethods-fire_events-for-pr

hub pull-request


# Celebrate!