Skip to content

Commit

Permalink
First pass at playing nice with multiple state machines
Browse files Browse the repository at this point in the history
  • Loading branch information
wfarr committed May 17, 2012
1 parent e0ca91e commit 972709d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 10 deletions.
32 changes: 26 additions & 6 deletions lib/active_model/transitions.rb
Expand Up @@ -27,7 +27,7 @@ module Transitions
included do included do
include ::Transitions include ::Transitions
after_initialize :set_initial_state after_initialize :set_initial_state
validates_presence_of :state validate :state_presence
validate :state_inclusion validate :state_inclusion
end end


Expand Down Expand Up @@ -56,20 +56,40 @@ def write_state(state_machine, state)
def write_state_without_persistence(state_machine, state) def write_state_without_persistence(state_machine, state)
ivar = state_machine.current_state_variable ivar = state_machine.current_state_variable
instance_variable_set(ivar, state) instance_variable_set(ivar, state)
self.state = state.to_s self.send(:"#{state_machine.name}=", state.to_s)
end end


def read_state(state_machine) def read_state(state_machine)
self.state && self.state.to_sym self.send(state_machine.name) && self.send(state_machine.name).to_sym
end end


def set_initial_state def set_initial_state
self.state ||= self.class.state_machine.initial_state.to_s if self.has_attribute?(:state) self.class.state_machines.each do |state_machine_array_container|
state_machine = state_machine_array_container[1]
name = state_machine.name
if self.send(name).nil? && self.has_attribute?(name)
self.send(:"#{name}=", state_machine.initial_state.to_s)
end
end
end

def state_presence
self.class.state_machines.each do |state_machine_array_container|
state_machine = state_machine_array_container[1]
name = state_machine.name
if self.send(name).nil?
self.errors.add(name, :presence)
end
end
end end


def state_inclusion def state_inclusion
unless self.class.state_machine.states.map{|s| s.name.to_s }.include?(self.state.to_s) self.class.state_machines.each do |state_machine_array_container|
self.errors.add(:state, :inclusion, :value => self.state) state_machine = state_machine_array_container[1]
name = state_machine.name
unless state_machine.states.map{|s| s.name.to_s }.include?(self.send(name))
self.errors.add(name, :inclusion, :value => self.send(name))
end
end end
end end
end end
Expand Down
12 changes: 8 additions & 4 deletions lib/transitions/event.rb
Expand Up @@ -27,12 +27,16 @@ class Event
def initialize(machine, name, options = {}, &block) def initialize(machine, name, options = {}, &block)
@machine, @name, @transitions = machine, name, [] @machine, @name, @transitions = machine, name, []
if machine if machine
machine.klass.send(:define_method, "#{name}!") do |*args| combined_name = name
machine.fire_event(name, self, true, *args) if machine.name != :default
combined_name = "#{machine.name}_#{name}"
end
machine.klass.send(:define_method, "#{combined_name}!") do |*args|
machine.fire_event(combined_name, self, true, *args)
end end


machine.klass.send(:define_method, name.to_s) do |*args| machine.klass.send(:define_method, combined_name) do |*args|
machine.fire_event(name, self, false, *args) machine.fire_event(combined_name, self, false, *args)
end end
end end
update(options, &block) update(options, &block)
Expand Down
1 change: 1 addition & 0 deletions lib/transitions/machine.rb
Expand Up @@ -44,6 +44,7 @@ def update(options = {}, &block)
end end


def fire_event(event, record, persist, *args) def fire_event(event, record, persist, *args)
event = event.gsub(/^#{self.name}_/, '').to_sym
state_index[record.current_state(@name)].call_action(:exit, record) state_index[record.current_state(@name)].call_action(:exit, record)
begin begin
if new_state = @events[event].fire(record, nil, *args) if new_state = @events[event].fire(record, nil, *args)
Expand Down

0 comments on commit 972709d

Please sign in to comment.