Dynamically instantiating an ActiveRecord Observer for multiple models
I'm trying to develop a plugin/gem at the moment which observes multiple models. Ideally, the observer should be instantiated automatically with just one singleton method...
class MyModel < ActiveRecord::Base
# a class method like this will tell the observer to observe this model
observe_me
end
My initial approach was to define class methods included into AR base:
module ClassMethods
def observe_me
@observe_me = true
end
def should_observe_me?
@observe_me
end
end
ActiveRecord::Base.extend(ClassMethods)
And then use this to detect which models to observe within the Observer:
class MyObserver < ActiveRecord::Observer
# this should observe all models where should_observe_me? #=> true
observe ActiveRecord::Base.descendants.select { |m| m.try(:should_observe_me?) }.map(&:model_name)
end
The problem that I'm running into is开发者_高级运维 that the observer is being loaded before the models are defined, so ActiveRecord has no descendants and MyObserver doesn't know which models to observe.
My next attempt was to hack around with ActiveRecord::Base.observers and ActiveRecord::Base.instantiate_observers but with no luck.
So, as it is at the moment:
Observer is defined but doesn't know which models to observe. Models are defined and flag themselves to be observed but the observer has already been observed.
Is there a way I can delay the loading of the observer until after the models are defined or can someone think of a better approach to this problem?
@gavin: The structure of the application initialization has changed in Rails3 -- this might be your problem.
When / how are you including the ClassMethods module? IF you are in Rails3, and IF you added "require 'observe_me'" to $ROOT/config/environment.rb, then you'd see the (mis)behavior you describe.
If so, instead, create $ROOT/config/initializers/my_extensions.rb and stick the "require ..." in there.
精彩评论