Как я могу предотвратить потерю конфигурации инициализатора в режиме разработки?

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

# config/initializers/my_engine.rb
MyEngine::SomeController.after_filter proc {
  # Do something in the host app
}, :only => :update

Это хорошо работает в производственной среде, но в режиме разработки proc вызывается только при первом запросе. Это потому, что классы перезагружаются, и эта конфигурация теряется, потому что она была сохранена в переменной класса. (Например,MyEngine::SomeController перезагружается из файла, в котором он находится, и так какafter_filter там не объявлено, оно не добавлено обратно.)

Некоторые Rails фон

В режиме разработки Rails использует следующую стратегию загрузки:

Код вapp каталог перезагружается при каждом запросе, при условии, что вы активно его меняете.Код вlib каталог, наряду сconfig/initializer файлы, загружаютсяодин раз, когда приложение загружается.

Файлы инициализатора обычно используются для настройки гемов. В прошлом у драгоценных камней в основном был код вlib каталог, поэтому запуск их конфигурации один раз был достаточным.

Как двигатели меняют вещи

Тем не менее, движки Rails имеют код вapp каталог: контроллеры, модели и т. д. Эти файлы перезагружаются в режиме разработки по каждому запросу. Поэтому конфигурация, как в моем примере выше, потеряна.

Введите to_prepare

Rails обеспечиваетconfig.to_prepare специально для решения этой проблемы: он запускается один раз в производстве и по каждому запросу в разработке.

Например, у нас есть это в application.rb, который отлично работает:

config.to_prepare do
  # set up class variables (after_filters, etc)
end

Однако, если я должен поместить конфигурацию всех моих двигателей вapplication.rbэто побеждает точкуconfig/initializers в порядке вещей.

Итак, для любой конфигурации классов в моих двигателяхapp каталоги, я хочу поместить этот код в файлы подconfig/initializers.

Вот мои вопросы.

Мне непонятно как получитьconfig в область действия в файле инициализатора. Я думаю, что это будетRails.application.config, Это правильно?Могу ли я добавить добавить несколькоto_prepare блоки? Я боюсь, что вызов его несколько раз перезапишет предыдущие блоки.Обновить

Как сказал @Frederick Cheung,Rails.application.config.to_prepare работает вconfig/initializer файлы, и можно использовать столько, сколько необходимо в различных файлах; каждый вызов добавляет свой блок в массив, поэтому ничего не перезаписывается.

Такрешение этой проблемы является:

# config/initializers/my_engine.rb
Rails.application.config.to_prepare do
  MyEngine::SomeController.after_filter proc {
    # Do something in the host app
  }, :only => :update
end

Одна вещь, которая все еще кажется странной: я ожидалto_prepare блок для вызовакаждый запрос в режиме разработки, но вместо этого он, кажется, вызывается случайным образом каждый третий запрос или около того. Я добавил блок:

Rails.application.config.to_prepare do
  Rails.logger.info "Running the prepare block!"
end

... перезапустил мое приложение и обновил страницу девять раз. Я только видел сообщение на 1-м, 5-м, 7-м и 9-м запросах. Я не уверен, что объясняет это поведение, но это объясняет, почему мой кодбез to_prepare работал с перерывами в разработке.

Ответы на вопрос(2)

Ваш ответ на вопрос