diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb index 7bad2397ae..707b1a0da6 100644 --- a/activemodel/lib/active_model/observing.rb +++ b/activemodel/lib/active_model/observing.rb @@ -1,7 +1,8 @@ require 'observer' require 'singleton' -require 'active_support/core_ext/string/inflections' require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/module/aliasing' +require 'active_support/core_ext/string/inflections' module ActiveModel module Observing @@ -39,6 +40,23 @@ module ActiveModel observers.each { |o| instantiate_observer(o) } end + # Wraps methods with before and after notifications. + # + # wrap_with_notifications :create, :save, :update, :destroy + def wrap_with_notifications(*methods) + methods.each do |method| + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{method}_with_notifications(*args, &block) + notify_observers(:before_#{method}) + result = #{method}_without_notifications(*args, &block) + notify_observers(:after_#{method}) + result + end + EOS + alias_method_chain(method, :notifications) + end + end + protected def instantiate_observer(observer) # string/symbol @@ -60,7 +78,7 @@ module ActiveModel end private - def notify(method) #:nodoc: + def notify_observers(method) self.class.changed self.class.notify_observers(method, self) end diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 01e41c04df..3aa0b8f1b5 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -349,7 +349,7 @@ module ActiveRecord result = send(method) end - notify(method) + notify_observers(method) return result end diff --git a/activeresource/lib/active_resource.rb b/activeresource/lib/active_resource.rb index 1dcb795a7d..fd4c199b48 100644 --- a/activeresource/lib/active_resource.rb +++ b/activeresource/lib/active_resource.rb @@ -34,6 +34,7 @@ module ActiveResource autoload :Connection, 'active_resource/connection' autoload :CustomMethods, 'active_resource/custom_methods' autoload :Formats, 'active_resource/formats' + autoload :Observing, 'active_resource/observing' autoload :Validations, 'active_resource/validations' autoload :HttpMock, 'active_resource/http_mock' end diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index 88a431a6d9..bc82139dac 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -804,8 +804,7 @@ module ActiveResource # my_company.size = 10 # my_company.save # sends PUT /companies/1 (update) def save - notify(:before_save) - (new? ? create : update).tap { notify(:after_save) } + new? ? create : update end # Deletes the resource from the remote service. @@ -821,8 +820,7 @@ module ActiveResource # new_person.destroy # Person.find(new_id) # 404 (Resource Not Found) def destroy - notify(:before_destroy) - connection.delete(element_path, self.class.headers).tap { notify(:after_destroy) } + connection.delete(element_path, self.class.headers) end # Evaluates to true if this resource is not new? and is @@ -997,20 +995,16 @@ module ActiveResource # Update the resource on the remote service. def update - notify(:before_update) connection.put(element_path(prefix_options), encode, self.class.headers).tap do |response| load_attributes_from_response(response) - notify(:after_update) end end # Create (i.e., \save to the remote service) the \new resource. def create - notify(:before_create) connection.post(collection_path, encode, self.class.headers).tap do |response| self.id = id_from_response(response) load_attributes_from_response(response) - notify(:after_create) end end @@ -1093,7 +1087,6 @@ module ActiveResource class Base extend ActiveModel::Naming - include CustomMethods, Validations - include ActiveModel::Observing + include CustomMethods, Observing, Validations end end diff --git a/activeresource/lib/active_resource/observing.rb b/activeresource/lib/active_resource/observing.rb new file mode 100644 index 0000000000..94836f4bb1 --- /dev/null +++ b/activeresource/lib/active_resource/observing.rb @@ -0,0 +1,10 @@ +module ActiveResource + module Observing + extend ActiveSupport::Concern + include ActiveModel::Observing + + included do + wrap_with_notifications :create, :save, :update, :destroy + end + end +end