lib/lazy_observers.rb in lazy_observers-0.0.2 vs lib/lazy_observers.rb in lazy_observers-0.0.3

- old
+ new

@@ -5,25 +5,28 @@ module LazyObservers def self.register_observed(klass) class_name = klass.name loaded << [klass, class_name] observers.each do |observer, observed| - connect!(observer, klass) if observed.include?(class_name) + connect!(observer.instance, klass) if observed.include?(class_name) end - (on_loads[class_name]||[]).each{|block| block.call(klass) } + (on_load_callbacks[class_name]||[]).each{|block| block.call(klass) } end - def self.register_observer(observer, classes) - observers[observer] = classes + def self.register_observer_instance(observer, classes) loaded.each do |klass, name| connect!(observer, klass) if classes.include?(name) end end + def self.register_observer_class(observer, classes) + observers[observer] = classes + end + def self.on_load(class_name, &block) - on_loads[class_name] ||= [] - on_loads[class_name] << block + on_load_callbacks[class_name] ||= [] + on_load_callbacks[class_name] << block end # to check you did not specify a class that does not exist def self.check_classes observers.values.flatten.uniq.each { |klass| klass.constantize } @@ -33,11 +36,11 @@ ActiveRecord::Base.send(:extend, LazyObservers::InheritedDebugger) end private - def self.on_loads + def self.on_load_callbacks @on_loads ||= {} end def self.observers @observers ||= {} @@ -46,39 +49,51 @@ def self.loaded @loaded ||= [] end def self.connect!(observer, klass) - observer.instance.observed_class_inherited(klass) + @connected ||= {} + return if @connected[[observer, klass]] + @connected[[observer, klass]] = true + observer.observed_class_inherited(klass) end -end -ActiveRecord::Base.send(:subclasses).each{|klass| LazyObservers.register_observed(klass) } - -ActiveRecord::Observer.class_eval do - def self.lazy_observe(*classes) - raise "pass class names, not classes or symbols!" unless classes.all?{|klass| klass.is_a?(String) } - define_method(:observed_classes) { Set.new } - LazyObservers.register_observer self, classes - end -end - -module LazyObservers module InheritedNotifier def inherited(subclass) LazyObservers.register_observed subclass super end end module InheritedDebugger def inherited(subclass) - @inherited_counter ||= 0 - @inherited_counter += 1 - puts "##{@inherited_counter} #{subclass}" + $lazy_observers_inherited_counter ||= 0 + $lazy_observers_inherited_counter += 1 + puts "##{$lazy_observers_inherited_counter} #{subclass}" puts caller puts "-" * 72 super + end + end +end + +descendants = (ActiveRecord::VERSION::MAJOR > 2 ? :descendants : :subclasses) +ActiveRecord::Base.send(descendants).each{|klass| LazyObservers.register_observed(klass) } + +ActiveRecord::Observer.class_eval do + def self.lazy_observe(*classes) + raise "pass class names, not classes or symbols!" unless classes.all?{|klass| klass.is_a?(String) } + define_method(:observed_classes) { Set.new } # prevent default of PostObserver -> Post + LazyObservers.register_observer_class self, classes + define_method(:lazy_observed_classes) { Set.new(classes) } + end + + # since AR uses respond_to? on the observer we need our observer to be fully defined before registering + alias_method :initialize_without_lazy, :initialize + def initialize + initialize_without_lazy + if defined?(lazy_observed_classes) + LazyObservers.register_observer_instance(self, lazy_observed_classes) end end end ActiveRecord::Base.send(:extend, LazyObservers::InheritedNotifier)