我想在我的Rails应用启动时设置一个类属性。它需要检查一些路由,因此需要在我的自定义代码运行之前加载路由。我无法找到一个可靠的地方。
这在“测试”环境中完美运行:
config.after_initialize do
Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}"
end
但不在“开发”环境中工作(路线为空)
现在我似乎通过在config.to_prepare
中运行相同的代码来开发模式,我理解在每个请求之前发生的代码。不幸的是,单独使用to_prepare
似乎不能在测试模式下工作,因此重复。
我很好奇为什么在测试模式中after_initialize之前加载路由,而不是在开发模式下。真的,这个最好的钩子是什么?是否有一个适用于所有环境的钩子?
的 的 *编辑*
穆的建议重新加载路线很棒。它使我能够在所有环境中对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 /中的代码做同样的事情,但我不确定这是否正确。
另一种选择是在to_prepare上应用mu的建议。这样可行,但在我的开发环境中,每次请求都重新加载路径似乎有明显的延迟,所以我不确定这是否是一个好的呼叫,尽管它至少是DRY。
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
答案 0 :(得分:23)
您可以在使用以下内容查看Rails.application.routes
之前强制加载路线:
Rails.application.reload_routes!
请在config/application.rb
:
config.after_initialize do
Rails.application.reload_routes!
Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}"
end
我做过类似的事情,需要检查路线(与/:slug
路线发生冲突),最后我将reload_routes!
和config.after_initialize
的检查结果放在一起做的。
答案 1 :(得分:2)
如果您在路由加载后尝试在初始化程序中运行代码,则可以尝试使用after:
选项:
initializer "name_of_initializer", after: :add_routing_paths do |app|
# do custom logic here
end
您可以在此处找到初始化事件:http://guides.rubyonrails.org/configuring.html#initialization-events