= What is transitions? transitions is a ruby state machine implementation based on Rick Olson’s ActiveModel::StateMachine. It was extracted from ActiveModel and turned into a gem when it got the axe in commit {db49c706b}[http://github.com/rails/rails/commit/db49c706b62e7ea2ab93f05399dbfddf5087ee0c]. I really encourage you to try {state_machine}[https://github.com/pluginaweek/state_machine] before using this gem. Currently I have no time to maintain the gem, if you want to add some new features - contact with me. == Quick Example require 'transitions' class Product include Transitions state_machine do state :available # first one is initial state state :out_of_stock, :exit => :exit_out_of_stock state :discontinued, :enter => lambda { |product| product.cancel_orders } event :discontinued do transitions :to => :discontinued, :from => [:available, :out_of_stock], :on_transition => :do_discontinue end event :out_of_stock do transitions :to => :out_of_stock, :from => [:available, :discontinued] end event :available do transitions :to => :available, :from => [:out_of_stock], :guard => lambda { |product| product.in_stock > 0 } end end end == Automatic scope generation `transitions` will automatically generate scopes for you if you are using AR: Given a model like this: class Order < ActiveRecord::Base include ActiveRecord::Transitions state_machine do state :pick_line_items state :picking_line_items end end you can use this feature a la: >> Order.pick_line_items => [] >> Order.create! => # >> Order.pick_line_items => [#] == Using on_transition Each event definition takes an optional "on_transition" argument, which allows you to execute methods on transition. You can pass in a Symbol, a String, a Proc or an Array containing method names as Symbol or String like this: event :discontinue do transitions :to => :discontinued, :from => [:available, :out_of_stock], :on_transition => [:do_discontinue, :notify_clerk] end == Timestamps If you'd like to note the time of a state change, Transitions comes with timestamps free! To activate them, simply pass the :timestamp option to the event definition with a value of either true or the name of the timestamp column. *NOTE - This should be either true, a String or a Symbol* # This will look for an attribute called exploded_at or exploded_on (in that order) # If present, it will be updated event :explode, :timestamp => true do transitions :from => :complete, :to => :exploded end # This will look for an attribute named repaired_on to update upon save event :rebuild, :timestamp => :repaired_on do transiions :from => :exploded, :to => :rebuilt end == Using with Rails This goes into your Gemfile: gem "transitions", :require => ["transitions", "active_record/transitions"] … and this into your AR model: include ActiveRecord::Transitions === A note about persistence The property used to persist the models’ state is named state (really!), which should be a string column wide enough to fit your longest state name. It should also be mentioned that #save! is called after every successful event. == Event execution flow On an event, with our quick example product going from :available to :discontinued it looks like this: 1. baby_ninja.discontinue!(:reason => :pirates) 2. call :exit handler of :available state 3. call :guard of :available to :discontinue transition within #discontinue event 4. call #event_failed(:event) and abort unless 3. returned true 5. call :on_transition(:reason => :pirates) of :available to :discontinue transition within #discontinue event 6. call :enter handler of :discontinue 7. call #event_fired(:available, :discontinue) 8. call #write_state(machine, :discontinue) 9. call #write_state_without_persistence(machine, :discontinue) 10. call baby_ninja#:success handler method of #discontinue event === A note about events When you declare an event discontinue, two methods are declared for you: discontinue and discontinue!. Both events will call write_state_without_persistence on successful transition, but only the bang(!)-version will call write_state. == Documentation, Guides & Examples - {Online API Documentation}[http://rdoc.info/github/qoobaa/transitions/master/Transitions] - Krzysiek Heród (aka {Netizer}[http://github.com/netizer]) wrote a nice {blog post}[http://dev.netizer.pl/transitions-state-machine-for-rails-3.html] about using Transitions in ActiveRecord. == Copyright Copyright (c) 2010 Jakub Kuźma, Timo Rößner. See LICENSE for details.