Динамическое создание экземпляра ActiveRecord Observer для нескольких моделей - PullRequest
3 голосов
/ 08 декабря 2010

Я сейчас пытаюсь разработать плагин / гем, который наблюдает за несколькими моделями.В идеале, наблюдатель должен создаваться автоматически только с помощью одного метода-одиночки ...

class MyModel < ActiveRecord::Base

  # a class method like this will tell the observer to observe this model
    observe_me

end

Мой первоначальный подход состоял в том, чтобы определить методы класса, включенные в базу AR:

module ClassMethods

  def observe_me
    @observe_me = true
  end

  def should_observe_me?
    @observe_me
  end
end
ActiveRecord::Base.extend(ClassMethods)

И затем использоватьчтобы определить, какие модели следует наблюдать в 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

Проблема, с которой я сталкиваюсь, заключается в том, что наблюдатель загружается до определения моделей, поэтому у ActiveRecord нет потомков, а у MyObserver нет 'не знаю, какие модели наблюдать.

Моя следующая попытка была взломать ActiveRecord :: Base.observers и ActiveRecord :: Base.instantiate_observers, но безуспешно.

Итак, как этона данный момент:

Наблюдатель определен, но не знает, какие модели наблюдать.Модели определены и помечают себя как наблюдаемые, но наблюдатель уже наблюдался.

Есть ли способ, которым я могу отложить загрузку наблюдателя до тех пор, пока модели не будут определены, или кто-то может подумать о лучшем подходе кэта проблема?

1 Ответ

0 голосов
/ 29 января 2011

@ gavin: Структура инициализации приложения изменилась в Rails3 - это может быть вашей проблемой.

Когда и как вы включаете модуль ClassMethods? Если вы находитесь в Rails3 и если вы добавили «require'me_me» в $ ROOT / config / environment.rb, то вы увидите (неправильное) поведение, которое вы описали.

Если это так, вместо этого создайте $ ROOT / config / initializers / my_extensions.rb и вставьте туда "require ...".

...