*Version 0.5.x > will only support Rails 3 / ActiveModel persistences. If you are using Rails 2 Please make sure you use the 0.4.x releases. There is a branch dedicated to that.*
This is the basics of the gem. Please check out the examples directory or tests for usage until this README gets fleshed out. Feel free to fork and modify as you please.
gem install stateflow
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
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.
require 'rubygems' require 'stateflow' # No persistence 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
require 'rubygems' require 'stateflow' # No persistence 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 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)
-
When transitioning states, the previous state from which you have transitioned to can be accessed via ‘_previous_state`. See tests for more information.
-
Fork the project.
-
Make your feature addition or bug fix.
-
Add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-
Send me a pull request. Bonus points for topic branches.
Copyright © 2010 Ryan Oberholzer. See LICENSE for details.