State machine that allows dynamic transitions for business workflows
= Stateflow
Now Rails 5 ready 😃
== INSTALL
gem install stateflow
== Usage
As you can see below, Stateflow’s API is very similar to AASM, but allows for a more dynamic state transition flow. Stateflow supports persistence/storage with Mongoid, MongoMapper, and ActiveRecord. Request any others or push them to me.
Stateflow defaults to ActiveRecord but you can set the persistence layer with:
Stateflow.persistence = :mongo_mapper
OR
Stateflow.persistence = :active_record
OR
Stateflow.persistence = :mongoid
Stateflow allows dynamic :to transitions with :decide. The result :decide returns needs to be one of the states listed in the :to array, otherwise it wont allow the transition. Please view the advanced example below for usage.
You can set the default column with the state_column function in the stateflow block. The default state column is “state”.
state_column :state
== Rails 3
Stateflow now automatically tries to detect your persistence from your applications default ORM config. If the ORM you are using does not have a persistence layer it will default to ActiveRecord.
== Basic Example
require ‘rubygems’
require ‘stateflow’
Stateflow.persistence = :none
class Stoplight
include Stateflow
stateflow do
initial :green
state :green, :yellow, :red
event :change_color do
transitions :from => :green, :to => :yellow
transitions :from => :yellow, :to => :red
transitions :from => :red, :to => :green
end
end
end
== Advanced Example
require ‘rubygems’
require ‘stateflow’
Stateflow.persistence = :none
class Test
include Stateflow
stateflow do
initial :love
state :love do
enter lambda { |t| p "Entering love" }
exit :exit_love
end
state :hate do
enter lambda { |t| p "Entering hate" }
exit lambda { |t| p "Exiting hate" }
end
state :mixed do
enter lambda { |t| p "Entering mixed" }
exit lambda { |t| p "Exiting mixed" }
end
event :b do
transitions :from => :love, :to => :hate, :if => :no_ice_cream
transitions :from => :hate, :to => :love
end
event :a do
transitions :from => :love, :to => [:hate, :mixed], :decide => :likes_ice_cream?
transitions :from => [:hate, :mixed], :to => :love
end
end
def likes_ice_cream?
rand(10) > 5 ? :mixed : :hate
end
def exit_love
p "Exiting love"
end
def no_ice_cream
rand(4) > 2 ? true : false
end
end
== Bang event vs non-bang event
Bang events will save the model after call, where the non bang event will just update the state and call the transitions. (ie. model.change! vs model.change)
== Extras
_previous_state
. See tests for more information.== Note on Patches/Pull Requests
== Copyright
Copyright © 2010 Ryan Oberholzer. See LICENSE for details.