README.rdoc in state_machine-0.9.4 vs README.rdoc in state_machine-0.10.0

- old
+ new

@@ -5,11 +5,11 @@ == Resources API -* http://rdoc.info/projects/pluginaweek/state_machine +* http://rdoc.info/github/pluginaweek/state_machine/master/frames Bugs * http://pluginaweek.lighthouseapp.com/projects/13288-state_machine @@ -35,18 +35,19 @@ Some brief, high-level features include: * Defining state machines on any Ruby class * Multiple state machines on a single class * Namespaced state machines -* before/after/around transition hooks with explicit transition requirements -* Integration with ActiveModel, ActiveRecord, DataMapper, MongoMapper, and Sequel +* before/after/around/failure transition hooks with explicit transition requirements +* Integration with ActiveModel, ActiveRecord, DataMapper, Mongoid, MongoMapper, and Sequel * State predicates * State-driven instance / class behavior * State values of any data type * Dynamically-generated state values * Event parallelization * Attribute-based event transitions +* Path analysis * Inheritance * Internationalization * GraphViz visualization creator Examples of the usage patterns for some of the above features are shown below. @@ -62,10 +63,11 @@ * Transition callbacks * Conditional transitions * State-driven instance behavior * Customized state values * Parallel events +* Path analysis Class definition: class Vehicle attr_accessor :seatbelt_on, :time_used @@ -77,10 +79,12 @@ after_transition :on => :repair, :do => :fix after_transition any => :parked do |vehicle, transition| vehicle.seatbelt_on = false end + after_failure :on => :ignite, :do => :log_start_failure + around_transition do |vehicle, transition, block| start = Time.now block.call vehicle.time_used += Time.now - start end @@ -167,10 +171,14 @@ end def fix # get the vehicle fixed by a mechanic end + + def log_start_failure + # log a failed attempt to start the vehicle + end end *Note* the comment made on the +initialize+ method in the class. In order for state machine attributes to be properly initialized, <tt>super()</tt> must be called. See StateMachine::MacroMethods for more information about this. @@ -233,11 +241,22 @@ # Human-friendly names can be accessed for states/events Vehicle.human_state_name(:first_gear) # => "first gear" Vehicle.human_alarm_state_name(:active) # => "active" Vehicle.human_state_event_name(:shift_down) # => "shift down" - Vehicle.human_alarm_state_event_name(:enable_alarm) # => "enable alarm" + Vehicle.human_alarm_state_event_name(:enable) # => "enable" + + # Available transition paths can be analyzed for an object + vehicle.state_paths # => [[#<StateMachine::Transition ...], [#<StateMachine::Transition ...], ...] + vehicle.state_paths.to_states # => [:parked, :idling, :first_gear, :stalled, :second_gear, :third_gear] + vehicle.state_paths.events # => [:park, :ignite, :shift_up, :idle, :crash, :repair, :shift_down] + + # Find all paths that start and end on certain states + vehicle.state_paths(:from => :parked, :to => :first_gear) # => [[ + # #<StateMachine::Transition attribute=:state event=:ignite from="parked" ...>, + # #<StateMachine::Transition attribute=:state event=:shift_up from="idling" ...> + # ]] == Integrations In addition to being able to define state machines on all Ruby classes, a set of out-of-the-box integrations are available for some of the more popular Ruby @@ -246,10 +265,11 @@ The integrations currently available include: * ActiveModel classes * ActiveRecord models * DataMapper resources +* Mongoid models * MongoMapper models * Sequel models A brief overview of these integrations is described below. @@ -303,10 +323,15 @@ # Generic transition callback *after* the transition is performed def after_transition(vehicle, transition) Audit.log(vehicle, transition) end + + # Generic callback after the transition fails to perform + def after_failure_to_transition(vehicle, transition) + Audit.error(vehicle, transition) + end end For more information about the various behaviors added for ActiveModel state machines and how to build new integrations that use ActiveModel, see StateMachine::Integrations::ActiveModel. @@ -416,18 +441,61 @@ around_transition do |transition, block| # mark start time block.call # mark stop time end + + # Generic callback after the transition fails to perform + after_transition_failure do |transition| + Audit.log(self, transition) # self is the record + end end *Note* that the DataMapper::Observer integration is optional and only available when the dm-observer library is installed. For more information about the various behaviors added for DataMapper state machines, see StateMachine::Integrations::DataMapper. +=== Mongoid + +The Mongoid integration adds support for automatically saving the record, +basic scopes, validation errors and callbacks. For example, + + class Vehicle + include Mongoid::Document + + state_machine :initial => :parked do + before_transition :parked => any - :parked, :do => :put_on_seatbelt + after_transition any => :parked do |vehicle, transition| + vehicle.seatbelt = 'off' # self is the record + end + around_transition :benchmark + + event :ignite do + transition :parked => :idling + end + + state :first_gear, :second_gear do + validates_presence_of :seatbelt_on + end + end + + def put_on_seatbelt + ... + end + + def benchmark + ... + yield + ... + end + end + +For more information about the various behaviors added for Mongoid state +machines, see StateMachine::Integrations::Mongoid. + === MongoMapper The MongoMapper integration adds support for automatically saving the record, basic scopes, validation errors and callbacks. For example, @@ -605,10 +673,11 @@ Test specific versions of integrations like so: rake test INTEGRATION=active_model VERSION=3.0.0 rake test INTEGRATION=active_record VERSION=2.0.0 rake test INTEGRATION=data_mapper VERSION=0.9.4 + rake test INTEGRATION=mongoid VERSION=2.0.0 rake test INTEGRATION=mongo_mapper VERSION=0.5.5 rake test INTEGRATION=sequel VERSION=2.8.0 == Caveats @@ -625,9 +694,10 @@ If using specific integrations: * ActiveModel[http://rubyonrails.org] integration: 3.0.0 or later * ActiveRecord[http://rubyonrails.org] integration: 2.0.0 or later * DataMapper[http://datamapper.org] integration: 0.9.4 or later +* Mongoid[http://mongoid.org] integration: 2.0.0 or later * MongoMapper[http://mongomapper.com] integration: 0.5.5 or later * Sequel[http://sequel.rubyforge.org] integration: 2.8.0 or later If graphing state machine: