StateMachine Gem
Caveats
JRuby / Rubinius**
around_transition
callbacks in ORM integrations won't work on JRuby since it doesn't support
continuations
Factory Girl
Dynamic initial states don't work because of the way factory_girl
builds objects. You can work around this in a few ways:
- Use a default state that is common across all objects and rely on events to determine the actual initial state for your object.
- Assuming you're not using state-driven behavior on initialization, you can re-initialize states after the fact:
# Re-initialize in FactoryGirl
FactoryGirl.define do
factory :vehicle do
after_build {|user| user.send(:initialize_state_machines, :dynamic => :force)}
end
end
# Alternatively re-initialize in your model
class Vehicle < ActiveRecord::Base
...
before_validation :on => :create {|user| user.send(:initialize_state_machines, :dynamic => :force)}
end
Native Extension
By default, StateMachine extends the Ruby core with a state_machine
method on Class
. All other
parts of the library are confined within the StateMachine
namespace. While this isn't wholly
necessary, it also doesn't have any performance impact and makes it truly feel like an extension to
the language. This is very similar to the way that you'll find yaml
, json
, or other libraries
adding a simple method to all objects just by loading the library.
However, if you'd like to avoid having StateMachine add this extension to the Ruby core:
require 'state_machine/core'
class Vehicle
extend StateMachine::MacroMethods
state_machine do
# ...
end
end
If you're using a gem loader like Bundler, you can explicitly indicate which file to load:
# In Gemfile
...
gem 'state_machine', :require => 'state_machine/core'