lib/stateful_enum/machine.rb in stateful_enum-0.4.0 vs lib/stateful_enum/machine.rb in stateful_enum-0.5.0
- old
+ new
@@ -2,20 +2,16 @@
module StatefulEnum
class Machine
def initialize(model, column, states, prefix, suffix, &block)
@model, @column, @states, @event_names = model, column, states, []
- @prefix = if prefix == true
- "#{column}_"
- elsif prefix
- "#{prefix}_"
- end
- @suffix = if suffix == true
- "_#{column}"
- elsif suffix
- "_#{suffix}"
- end
+ @prefix = if prefix
+ prefix == true ? "#{column}_" : "#{prefix}_"
+ end
+ @suffix = if suffix
+ suffix == true ? "_#{column}" : "_#{suffix}"
+ end
# undef non-verb methods e.g. Model#active!
states.each do |state|
@model.send :undef_method, "#{@prefix}#{state}#{@suffix}!"
end
@@ -29,31 +25,40 @@
@event_names << name
end
class Event
def initialize(model, column, states, prefix, suffix, name, &block)
- @states, @name, @transitions, @before, @after = states, name, {}, nil, nil
+ @states, @name, @transitions, @before, @after = states, name, {}, [], []
instance_eval(&block) if block
transitions, before, after = @transitions, @before, @after
new_method_name = "#{prefix}#{name}#{suffix}"
# defining event methods
model.class_eval do
# def assign()
detect_enum_conflict! column, new_method_name
+
+ # defining callbacks
+ define_callbacks new_method_name
+ before.each do |before_callback|
+ model.set_callback new_method_name, :before, before_callback
+ end
+ after.each do |after_callback|
+ model.set_callback new_method_name, :after, after_callback
+ end
+
define_method new_method_name do
to, condition = transitions[send(column).to_sym]
#TODO better error
if to && (!condition || instance_exec(&condition))
#TODO transaction?
- instance_eval(&before) if before
- original_method = self.class.send(:_enum_methods_module).instance_method "#{prefix}#{to}#{suffix}!"
- ret = original_method.bind(self).call
- instance_eval(&after) if after
- ret
+ run_callbacks new_method_name do
+ original_method = self.class.send(:_enum_methods_module).instance_method "#{prefix}#{to}#{suffix}!"
+ original_method.bind(self).call
+ end
else
false
end
end
@@ -64,11 +69,14 @@
end
# def can_assign?()
detect_enum_conflict! column, "can_#{new_method_name}?"
define_method "can_#{new_method_name}?" do
- transitions.key? send(column).to_sym
+ state = send(column).to_sym
+ return false unless transitions.key? state
+ _to, condition = transitions[state]
+ !condition || instance_exec(&condition)
end
# def assign_transition()
detect_enum_conflict! column, "#{new_method_name}_transition"
define_method "#{new_method_name}_transition" do
@@ -98,14 +106,14 @@
def all
@states
end
def before(&block)
- @before = block
+ @before << block
end
def after(&block)
- @after = block
+ @after << block
end
end
end
end