Я пытаюсь записать плагин, который определяет модель 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:: Соединение'
который приводит меня думать, что это пытается загрузить мою сменную модель перед установкой соединения с базой данных. Как я заставляю его загрузить плагин после остальной части моего кода приложения?
Я постараюсь решить как ошибку, с которой я столкнулся, так и общий вопрос, указанный в заголовке.
Я разобрался, в чем проблема. Как я сказал в комментарии выше, проблема в том, что 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
) после все будет загружено и инициализировано, но до поступают любые запросы. Наслаждайтесь.