Как расширить класс из инициализатора и перезагрузить его в среде разработки? - PullRequest
11 голосов
/ 07 октября 2009

Я расширяю класс (который есть в плагине), включая модуль, это делается в инициализаторе.

require 'qwerty/core/user'
User.send :include, Qwerty::Core::Extensions::User

Однако при разработке перед каждым запросом (и после перезагрузки! Вызывается в консоли) все модели перезагружаются, но поскольку инициализаторы не запускаются снова, модуль не включен. Оставление модели с «отсутствующими частями».

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

А пока я просто добавил before_filter, который включает модуль, если он находится в среде разработки. Но у меня есть копия / вставка и дубликат кода в инициализаторе и контроллере приложения.

  # Class extensions in initalizers are over-writtern each request
  def development_loading
    if RAILS_ENV == 'development'      
      User.send :include, Qwerty::Core::Extensions::User
    end
  end

Есть ли лучший способ?

В качестве дополнительного примечания плагин - мой, поэтому я мог бы добавить к нему код, но расширения, содержащиеся в модуле, могут присутствовать не всегда ...

Ответы [ 5 ]

11 голосов
/ 09 октября 2009

environment.rb

config.to_prepare do
  User.send :include, Qwerty::Core::Extensions::User
end

Код блока запускается перед каждым запросом в режиме разработки и один раз в рабочем режиме.

6 голосов
/ 26 декабря 2011

В Rails 3.x вы можете настроить блок на запуск каждый раз, когда происходит перезагрузка (в режиме разработки или когда config.cache_classes = false). Это будет идти в инициализаторе:

ActionDispatch::Callbacks.to_prepare do
    # configure stuff or initialize
end
3 голосов
/ 19 ноября 2010

Чуть более изящное решение, чем принятое, поскольку его можно поместить в инициализатор:

require 'dispatcher'

Dispatcher.to_prepare do
  # stuff that needs to happen once per initialization
end
1 голос
/ 09 октября 2009

Сначала я собирался что-то посоветовать по поводу добавления каталога 'development' в начало пути загрузки в режиме разработки, чтобы ваши ревизии всегда сначала перезагружались ... Но потом мне пришло в голову, что вы сказали что-то сбивает с толку.

Модель, которую вы пытаетесь расширить. Он находится в плагине? Плагины не должны предполагать для перезагрузки по умолчанию в режиме разработки, если только приложение явно не сообщит, что они должны в своей конфигурации, установив для Config.reload_plugins? значение false.

Но если по какой-то причине ваш плагин все равно перезагружается и вы не этого хотите, вы можете поместить это в init.rb вашего плагина, чтобы явно сказать это не должен перезагружаться:

Dependencies.load_once_paths << lib_path

См. Документацию Rails по классу Configuration для более подробной информации: http://api.rubyonrails.org/classes/Rails/Configuration.html#M002536

0 голосов
/ 07 октября 2009

Почему вы используете инициализаторы для включения функциональности?

Попробуйте вместо этого:

require 'qwerty/core/user'
class User < ActiveRecord::Base
  include Qwerty::Core::Extensions::User
  # bla bla
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...