Skip to content

Instantly share code, notes, and snippets.

@jkatz
Created February 5, 2010 21:27
Show Gist options
  • Save jkatz/296265 to your computer and use it in GitHub Desktop.
Save jkatz/296265 to your computer and use it in GitHub Desktop.
Simple State Machine for an ActiveRecord model (see "after_initialize")
module StateMachine
# assumption: just using "state" as our column. easy enough to change
def self.included(mod)
mod.extend ClassMethods
super
end
module ClassMethods
def initial_state(state)
state(state)
self.class_eval do
define_method(:after_initialize) do
self.state ||= state.to_s
end
end
end
def state(state)
@@states ||= []
@@states << state
self.class_eval do
define_method("#{state}?".to_sym) do
state == self.state.to_sym
end
end
end
def event(event, transitions)
@@events ||= {}
@@events[event] = transitions
self.class_eval do
define_method("#{event}!") do
current_state = state.to_sym
transition = @@events[event].select { |old, new| old == current_state }.last
self.update_attribute(:state, transition.last.to_s) if transition && @@states.include?(transition.last)
self
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment