lib/mongoid/edge-state-machine.rb in edge-state-machine-0.0.2 vs lib/mongoid/edge-state-machine.rb in edge-state-machine-0.0.3
- old
+ new
@@ -3,31 +3,76 @@
extend ActiveSupport::Concern
included do
include ::EdgeStateMachine
after_initialize :set_initial_state
- validates_presence_of :state
+ validate :state_variables_presence
validate :state_inclusion
end
+ # The optional options argument is passed to find when reloading so you may
+ # do e.g. record.reload(:lock => true) to reload the same record with an
+ # exclusive row lock.
+ def reload
+ super.tap do
+ @current_states = {}
+ end
+ end
+
protected
- def write_state(state_machine, state)
- self.state = state.to_s
- save!
+ def load_from_persistence(machine_name)
+ machine = self.class.state_machines[machine_name]
+ send machine.persisted_variable_name.to_s
end
- def read_state(state_machine)
- self.state.to_sym
+ def save_to_persistence(new_state, machine_name, options = {})
+ machine = self.class.state_machines[machine_name]
+ send("#{machine.persisted_variable_name}=".to_sym, new_state)
+ save! if options[:save]
end
def set_initial_state
- self.state ||= self.class.state_machine.initial_state.to_s
+ # set the initial state for each state machine in this class
+ self.class.state_machines.keys.each do |machine_name|
+ machine = self.class.state_machines[machine_name]
+
+ if persisted_variable_value(machine.persisted_variable_name).blank?
+ if load_from_persistence(machine_name)
+ send("#{machine.persisted_variable_name}=".to_sym, load_from_persistence(machine_name))
+ else
+ send("#{machine.persisted_variable_name}=".to_sym, machine.initial_state_name)
+ end
+ end
+ end
end
+ def persisted_variable_value(name)
+ send(name.to_s)
+ end
+
+ def state_variables_presence
+ # validate that state is in the right set of values
+ self.class.state_machines.keys.each do |machine_name|
+ machine = self.class.state_machines[machine_name]
+ validates_presence_of machine.persisted_variable_name.to_sym
+ end
+ end
+
def state_inclusion
- unless self.class.state_machine.states.map{|s| s.name.to_s }.include?(self.state.to_s)
- self.errors.add(:state, :inclusion, :value => self.state)
+ # validate that state is in the right set of values
+ self.class.state_machines.keys.each do |machine_name|
+ machine = self.class.state_machines[machine_name]
+ unless machine.states.keys.include?(persisted_variable_value(machine.persisted_variable_name).to_sym)
+ self.errors.add(machine.persisted_variable_name.to_sym, :inclusion, :value => persisted_variable_value(machine.persisted_variable_name))
+ end
+ end
+ end
+
+ module ClassMethods
+ def add_scope(state, machine_name)
+ machine = state_machines[machine_name]
+ scope state.name, where(machine.persisted_variable_name.to_sym => state.name.to_s)
end
end
end
end