在加载*路由后运行*的Rails初始化程序?

我想在我的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的建议。 这样可行,但在我的开发环境中,每次请求都重新加载路由似乎有明显的延迟,所以我不确定这是否是一个好的呼叫,尽管它至少是干的。

 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

如果您在路由加载后尝试在初始化程序中运行代码,则可以尝试使用after:选项:

 initializer "name_of_initializer", after: :add_routing_paths do |app| # do custom logic here end 

您可以在此处找到初始化事件: http : //guides.rubyonrails.org/configuring.html#initialization-events