Skip to content

Instantly share code, notes, and snippets.

@orbanbotond
Created November 6, 2013 15:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orbanbotond/7337512 to your computer and use it in GitHub Desktop.
Save orbanbotond/7337512 to your computer and use it in GitHub Desktop.
mongoid observers
module MyObservers
module Document
module ClassMethods
def observers= (*observers)
declared_observers.replace(observers.flatten)
end
def declared_observers
@declared_observers ||= []
end
def instantiated_observers
@instantiated_observers ||= []
end
def instantiate_observers
declared_observers.each { |o| instantiate_observer(o) }
end
def instantiate_observer(observer)
if observer.respond_to?(:to_sym)
observer = observer.to_s.camelize.constantize
end
instantiated_observers << observer.new
end
end
def add_observer!(klass)
observers << klass
end
def observers
@observing_observers ||=[]
end
end
class Observer
def initialize
# observed_classes.each { |klass| observe___(klass) }
observed_classes
end
def observed_classes
# SLOWWWWW
# Uncomment the following line and the tests will be slow...
# c = UserInvitation.class
# klass = self.class.name[/(.*)Observer/, 1].constantize
# [klass]
[]
end
def observe___(klass)
# define_callbacks klass
end
def update(observed_method, object, *extra_args, &block) #:nodoc:
return if !respond_to?(observed_method) || disabled_for?(object)
send(observed_method, object, *extra_args, &block)
end
def define_callbacks(klass)
observer = self
observer_name = observer.class.name.underscore.gsub('/', '__')
callbacks = [ "after_initialize", "after_build", "before_validation",
"after_validation", "before_create", "around_create",
"after_create", "after_find", "before_update",
"around_update", "after_update", "before_upsert",
"around_upsert", "after_upsert", "before_save",
"around_save", "after_save", "before_destroy",
"around_destroy", "after_destroy" ]
callbacks.each do |callback|
next unless respond_to?(callback)
callback_meth = :"_notify_#{observer_name}_for_#{callback}"
unless klass.respond_to?(callback_meth)
klass.send(:define_method, callback_meth) do |&block|
observer.update(callback, self, &block)
end
klass.send(callback, callback_meth)
end
end
end
end
end
module Mongoid
module Document
extend MyObservers::Document::ClassMethods
include MyObservers::Document
end
end
Mongoid::Document.observers = :user_invitation_observer
ActiveSupport.on_load(:mongoid) do
Mongoid::Document.instantiate_observers
end
@chamnap
Copy link

chamnap commented Apr 16, 2014

I wrote up this gem, https://github.com/chamnap/mongoid-observers/. Please, have a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment