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