Как заставить Rails загрузить плагин * после * кода приложения?
-
29-09-2019 - |
Вопрос
Я пытаюсь написать плагин, который определяет модель Mongomapper. Проблема в том, что когда я бегу script/console
, Я получаю эту ошибку:
/home/helder/.rvm/gems/ruby-1.8.7-p249/gems/mongo_mapper-0.8.2/lib/mongo_mapper/connection.rb:29:in
`` База данных ': nameError: ненициализированная переменная класса @@ database_name в mongomapper :: connection`
Что заставляет меня думать, что он пытается загрузить мою модель плагина перед настройкой подключения к базе данных. Как заставить его загрузить плагин после остальная часть моего кода приложения?
Решение
Я постараюсь обратиться к ошибке, с которой я столкнулся, так и общий вопрос, как указано в заголовке.
Конкретная ошибка
Я понял, в чем проблема. Как я уже говорил в комментарии выше, проблема заключается в том, что Rails (2.3.8) при использовании Activerecord сначала устанавливает подключение к базе данных, а затем загружает драгоценные камни, затем плагины (в данном порядке). Поэтому, если у вас есть какие -либо плагины, которые должны получить доступ к базе данных во время их инициализации (то есть внутри плагина init.rb
или какой -то другой файл require
D от этого), все работает нормально.
Но при использовании Mongomapper, Rails загружает Mongomapper's классы Вместе со всеми другими драгоценными камнями/плагинами, но не настраивает его соединение (Rails не делает этого, и плагин тоже не запускает его сам). Способ, который в настоящее время рекомендуется на Документация Mongodb это создать такой инициализатор, как это:
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = "#myapp-#{Rails.env}"
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
MongoMapper.connection.connect_to_master if forked
end
end
Но так как плагины инициализируются до файлы в config/initializers
запускаются, если вы попытаетесь определить модель Mongomapper, как только она дойдет до вызова, который доступ к базе данных (например, вызов к key
Метод класса), бум. Вы получаете ошибку, указанную в вопросе.
Один из способов решить это - нет требуется в init.rb
Файлы, которые нуждаются в базе данных, но скорее добавляют их в путь нагрузки (если они не в lib/
или app/models
, который автоматически добавляет в путь нагрузки). Таким образом, модели будут только require
D By Rails 'Auto Class Loader, когда их ссылаются, что обычно находится в коде вашего приложения. К тому времени подключение DB уже будет настроено. Конечно, это работает, только если вы действительно не Нужно ссылаться на эти классы во время инициализации вашего плагина. В противном случае читайте дальше.
Общий вопрос
Как заставить Rails загрузить плагин после код инициализации?
На вашем плагине init.rb
, бросать что-либо Это нужно ждать внутри этого блока:
config.after_initialize do
# require my models
# do this
# do that
end
Тот config
переменная та же самая передана к блоку, который передается в Rails::Initializer.run
внутри вашего config/environment.rb
Файл и доступен для вашего плагина init.rb
по железной дороге без дополнительных затрат.
Все, что вы положили внутри этого блока, будет выполнено ( Rails::Initializer#after_initialize
) после Все закончено загружать и инициализироваться, но до Приходят любые запросы. Наслаждайтесь.