Rails пользовательский класс static init - PullRequest
1 голос
/ 25 марта 2011

Учитывая класс

# foo.rb
class Foo
  Rails.logger.info "Foo loaded"
end

находится в #{Rails.root}/app/lib. Я добавил к config/application.rb следующее:

config.autoload_paths += %W(#{config.root}/app/lib)

Когда я запускаю рельсы через rails s или rails console, я бы хотел, чтобы Foo loaded был зарегистрирован. Это упрощенная версия того, что я собираюсь сделать, но она адекватно демонстрирует то, чего я пытаюсь достичь. В настоящее время происходит то, что при запуске ничего не регистрируется. Затем, когда я использую Foo, например, с Foo.new, я вижу сообщение в журнале.

Каков наиболее подходящий метод в Rails 3 для достижения этой цели, чтобы я видел записанное сообщение при запуске?

Ответы [ 3 ]

2 голосов
/ 28 марта 2011

Вот что я в итоге сделал:

(1) В классе app/lib/foo.rb я добавил статический метод, требующий соответствующие файлы

def self.load_foos
  Dir["#{Rails.root}/app/lib/foos/*_foo.rb"].each do |file|
    require file
  end
end

(2) вfoo.rb, я добавил статический метод, чтобы подклассы могли регистрировать себя

def self.register 
  if @@subclasses.include?( self.registration_symbol )
    raise FooExceptionSymbolAlreadyUsed, "symbol [#{self.registration_symbol}] is already in use."
  end
  @@subclasses[self.registration_symbol] = [self.registration_priority,self]
end

(3) Я создал каталог на app/lib/foos, где я поместил различные подклассы foo и назвал их this_foo.rbи that_foo.rb.

(4) В подкласс app/lib/foos/this_foo.rb я добавил следующее

class Foos::ThisFoo < Foo

  def self.registration_symbol
    :this
  end

  def self.registration_priority
    100
  end

  # other methods removed to make example easier to read

  register
end

(5) Я добавил config/initializers/load_foos.rb, который просто имел

Foo::load_foos

Любой подкласс Foo, который я вставил в app/lib/foos/ и правильно назвал, будет автоматически загружаться при запуске.Каждый подкласс переопределяет и реализует методы для registration_symbol и registration_priority (приоритет используется позже для сортировки перечисления), а символ используется в методе create.

Таким образом, я могу опубликовать спецификацию для моих разработчиков, которая показывает им, какие методы Foo реализовать в их подклассах и как зарегистрировать их и где сохранить, а затем приложение Rails автоматически загрузит эти файлы вследующий запуск.

0 голосов
/ 25 марта 2011

Среда разработки Rails, хотя и замечательна для разработки, немного странна по загрузке и требованию.

Однако, если вы используете стандартное требование Ruby, вы найдете вещи более предсказуемыми.Я бы посоветовал вам оставить как можно больше, используя рельсы config.autoload_paths

Для кода, который вы хотите всегда запрашивать, просто добавьте require 'app/lib/foo' в самом конце вашего config / application.rb, внеопределение модуля.

Кроме того, обычно lib находится в корне каталога rails, а не в папке приложения.Это был тип или сознательный выбор?

0 голосов
/ 25 марта 2011

У меня была похожая ситуация - у меня была целая куча констант в моих моделях, которые действительно нужно было загружать только один раз, когда запускался Rails, но, казалось, перезагружался каждый раз, когда я обращался к этой модели. Я решил это следующим образом:

  1. Я определил константы в файле в config / initiaizers (файлы загружаются автоматически при запуске)
  2. Я добавил методы к своим моделям, которые обращались к этим константам

Если вы имеете дело с константами (например, Foo::PI = 42), это должно сработать для вас. Если вы определяете методы ... может быть? Вы можете столкнуться с некоторыми проблемами в режиме разработки, когда Rails перезагружает измененные классы - я не уверен.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...