From a9eefa97dc0f153a28576589e4ffc5b4ec8cd98d Mon Sep 17 00:00:00 2001 From: Vladimir Meremyanin Date: Thu, 21 Feb 2013 12:01:59 +0400 Subject: [PATCH] Breaking changes: success/error callbacks called in context of record, not with record as argument. Refactored callbacks in event.rb, added support for inline definition of success/error callbacks. --- lib/aasm/aasm.rb | 4 +- lib/aasm/supporting_classes/event.rb | 53 ++++------------------ spec/unit/supporting_classes/event_spec.rb | 6 +-- 3 files changed, 15 insertions(+), 48 deletions(-) diff --git a/lib/aasm/aasm.rb b/lib/aasm/aasm.rb index 8ce5bf82..330eee63 100644 --- a/lib/aasm/aasm.rb +++ b/lib/aasm/aasm.rb @@ -184,7 +184,7 @@ def aasm_fire_event(name, options, *args) persist_successful = true if persist persist_successful = aasm_set_current_state_with_persistence(new_state_name) - event.execute_success_callback(self) if persist_successful + event.fire_callbacks(:success, self) if persist_successful else self.aasm_current_state = new_state_name end @@ -213,7 +213,7 @@ def aasm_fire_event(name, options, *args) end end rescue StandardError => e - event.execute_error_callback(self, e) + event.fire_callbacks(:error, self, e) end end end diff --git a/lib/aasm/supporting_classes/event.rb b/lib/aasm/supporting_classes/event.rb index e2ea1c59..3982d5b7 100644 --- a/lib/aasm/supporting_classes/event.rb +++ b/lib/aasm/supporting_classes/event.rb @@ -1,7 +1,7 @@ module AASM module SupportingClasses class Event - attr_reader :name, :success, :options + attr_reader :name, :options def initialize(name, options = {}, &block) @name = name @@ -40,11 +40,8 @@ def all_transitions @transitions end - def fire_callbacks(action, record) - action = @options[action] - action.is_a?(Array) ? - action.each {|a| _fire_callbacks(a, record)} : - _fire_callbacks(action, record) + def fire_callbacks(action, record, *args) + invoke_callbacks(@options[action], record, args) end def ==(event) @@ -55,41 +52,9 @@ def ==(event) end end - def execute_success_callback(obj, success = nil) - callback = success || @success - case(callback) - when String, Symbol - obj.send(callback) - when Proc - callback.call(obj) - when Array - callback.each{|meth|self.execute_success_callback(obj, meth)} - end - end - - def execute_error_callback(obj, error, error_callback=nil) - callback = error_callback || @error - raise error unless callback - case(callback) - when String, Symbol - raise NoMethodError unless obj.respond_to?(callback.to_sym) - obj.send(callback, error) - when Proc - callback.call(obj, error) - when Array - callback.each{|meth|self.execute_error_callback(obj, error, meth)} - end - end - private def update(options = {}, &block) - if options.key?(:success) then - @success = options[:success] - end - if options.key?(:error) then - @error = options[:error] - end @options = options if block then instance_eval(&block) @@ -123,12 +88,14 @@ def _fire(obj, test, to_state=nil, *args) result end - def _fire_callbacks(action, record) - case action + def invoke_callbacks(code, record, args) + case code when Symbol, String - record.send(action) + record.send(code, *args) when Proc - record.instance_eval &action + record.instance_exec(*args, &code) + when Array + code.each {|a| invoke_callbacks(a, record, args)} end end @@ -142,7 +109,7 @@ def transitions(trans_opts) @transitions << AASM::SupportingClasses::StateTransition.new(trans_opts) if @transitions.empty? && trans_opts[:to] end - [:after, :before].each do |callback_name| # add :success, :error ? + [:after, :before, :error, :success].each do |callback_name| define_method callback_name do |*args, &block| options[callback_name] = Array(options[callback_name]) options[callback_name] << block if block diff --git a/spec/unit/supporting_classes/event_spec.rb b/spec/unit/supporting_classes/event_spec.rb index 5aee2d6f..e5aec0f7 100644 --- a/spec/unit/supporting_classes/event_spec.rb +++ b/spec/unit/supporting_classes/event_spec.rb @@ -14,7 +14,7 @@ end it 'should set the success callback' do - event.success.should == :success_callback + event.options[:success].should == :success_callback end it 'should set the after callback' do @@ -133,7 +133,7 @@ it "if passed an array of strings and/or symbols and/or procs" do ThisNameBetterNotBeInUse.instance_eval { - aasm_event :with_array_including_procs, :success => [:success_callback1, 'success_callback2', lambda { |obj| obj.proc_success_callback }] do + aasm_event :with_array_including_procs, :success => [:success_callback1, 'success_callback2', lambda { proc_success_callback }] do transitions :to => :array, :from => [:initial] end } @@ -147,7 +147,7 @@ it "if it's a proc" do ThisNameBetterNotBeInUse.instance_eval { - aasm_event :with_proc, :success => lambda { |obj| obj.proc_success_callback } do + aasm_event :with_proc, :success => lambda { proc_success_callback } do transitions :to => :proc, :from => [:initial] end }