Как заставить направляющие загрузить плагин *после* код приложения?

Я пытаюсь записать плагин, который определяет модель 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:: Соединение'

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

6
задан ThinkingStiff 23 July 2012 в 18:09
поделиться

1 ответ

Я постараюсь решить как ошибку, с которой я столкнулся, так и общий вопрос, указанный в заголовке.

Конкретная ошибка

Я разобрался, в чем проблема. Как я сказал в комментарии выше, проблема в том, что Rails (2.3.8) при использовании ActiveRecord сначала устанавливает соединение с базой данных, затем загружает драгоценные камни, а затем плагины (в этом порядке). Поэтому, если у вас есть какие-либо плагины, которым требуется доступ к базе данных во время их инициализации (то есть внутри плагина init.rb или какого-либо другого файла , требуется d этим), все работает отлично.

Но при использовании MongoMapper Rails загружает классы MongoMapper вместе со всеми другими драгоценными камнями / плагинами, но не устанавливает его соединение (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

Но поскольку плагины инициализируются до запуска файлов в конфигурациях / инициализаторах , если вы попытаетесь определить модель MongoMapper, как только она получит вызов, обращающийся к базе данных (например, вызов метода класса key ), BOOM. Вы получаете ошибку, указанную в вопросе.

Один из способов решить эту проблему - не требовать в init.rb файлов, которым нужна база данных, а просто добавить их в путь загрузки (если они не в lib / или app / models , которые Rails автоматически добавляет к пути загрузки). Таким образом, модели будут потребовать d автозагрузчиком классов Rails, когда на них будут ссылаться, которые обычно находятся внутри кода вашего приложения. К тому времени соединение с базой данных уже будет установлено. Конечно, это работает только в том случае, если вам действительно не нужно ссылаться на эти классы во время инициализации вашего плагина. В противном случае читайте дальше.

Общий вопрос

Как заставить Rails загружать плагин после кода инициализации?

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

config.after_initialize do
  # require my models
  # do this
  # do that
end

Эта переменная config такая же, как и переданная в блок, который передается в Rails :: Initializer.run внутри вашего config / environment.rb , и Rails делает его доступным для init.rb вашего плагина без каких-либо дополнительных затрат.

Все, что вы помещаете в этот блок, будет выполнено (с помощью Rails :: Initializer # after_initialize ) после все будет загружено и инициализировано, но до поступают любые запросы. Наслаждайтесь.

10
ответ дан 10 December 2019 в 00:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: