Я хочу установить атрибут класса при запуске моего приложения Rails. Это требует проверки некоторых маршрутов, поэтому их нужно загрузить до запуска моего пользовательского кода. У меня проблемы с поиском надежного места для подключения.
Это ОТЛИЧНО работает в «тестовой» среде:
config.after_initialize do
Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}"
end
Но не работает в «среде разработки» (маршруты empty)
На данный момент у меня, кажется, что-то работает в режиме разработки, выполняя тот же код в config.to_prepare
, который, как я понимаю, происходит перед каждым запросом. К сожалению, использование только to_prepare
не работает в тестовом режиме, отсюда и дублирование.
Мне любопытно, почему маршруты загружаются до after_initialize в тестовом режиме, а не в режиме разработки. И действительно, какой крючок для этого лучше всего? Есть ли один хук, который будет работать для всех сред?
* EDIT *
Предложение mu по перезагрузке маршрутов было отличным. Это дало мне постоянный доступ к маршрутам в after_initialize во всех средах. Однако для моего варианта использования я думаю, что мне все еще нужно запускать код из to_prepare, поскольку я устанавливаю атрибут класса в модели, и модели перезагружаются перед каждым запросом.
Вот что я в итоге сделал.
[:after_initialize, :to_prepare].each do |hook|
config.send(hook) do
User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq
end
end
Мне это кажется немного беспорядочным.Думаю, я бы предпочел сделать что-то вроде:
config.after_initialize do
User.exclude_routes_from_usernames!
end
config.to_prepare do
User.exclude_routes_from_usernames!
end
Но я не уверен, что User
- подходящее место для изучения Rails.application.routes
. Думаю, я мог бы сделать то же самое с кодом в lib /, но я тоже не уверен, что это правильно.
Другой вариант - просто применить предложение mu к to_prepare. Это работает, но, похоже, наблюдается заметная задержка перезагрузки маршрутов при каждом запросе в моей среде разработки, поэтому я не уверен, что это хороший вызов, хотя, по крайней мере, это СУХОЙ.
config.to_prepare do
Rails.application.reload_routes!
User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq
end