当我的Rails应用程序启动时,我想设置一个类属性.它需要检查一些路由,所以在我的自定义代码运行之前需要加载路由.我无法找到一个可靠的地方挂钩.
这在“测试”环境中可以完美地工作:
config.after_initialize do Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}" end
但它在“开发”环境中无效(路由为空)
现在,我似乎通过在config.to_prepare中运行相同的代码,在开发模式下工作,我明白每个请求之前都会发生.不幸的是,单独使用to_prepare似乎不能在测试模式下工作,因此重复.
我很好奇为什么路由在测试模式下的after_initialize之前加载,但不是在开发模式下.真的,这是最好的钩子?是否有一个钩子可以适用于所有环境?
*编辑*
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
但我不知道用户是否正确检查Rails.application.routes的地方.我想我可以用lib / 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
解决方法
您可以在查看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.