我正在构建一个使用OmniAuth的Rails引擎。 OmniAuth需要在Rails中间件堆栈中添加一些中间件,根据OmniAuth,建议的方法是在初始化程序中执行此操作。我已经尝试过了,我已经成功地在gem中创建了一个初始化器,它在Rails应用程序启动时被加载。现在,我正在尝试为我的gem添加一些配置选项,我希望gem用户能够创建另一个初始化程序,以便在gem的初始化程序工作之前配置gem BEFORE。
我发现所有引擎中的任何初始化器都是先加载的。然后加载Rails应用程序中的初始化程序。我希望我能够以这样的方式命名初始化器,以便我可以控制加载顺序,但是Rails app初始化器仍然在gem的初始化器之后处理。这对我来说非常有意义,但它给我留下了初始化程序加载顺序问题。 Rails应用程序将持续使用,当它有机会配置gem时,gem已经完成了它的工作。
我的下一个想法是在引擎的Railtie中使用after_initialize
回调。在大多数情况下,这可能会起作用,但在这个特定的用例中它没有帮助。在调用after_initialize
时,中间件堆栈被冻结并且无法更改(这使得对于仅用于更改中间件堆栈的代码无用)。
此时,我只看到一个解决方法。 Rails应用程序必须在application.rb中配置gem,以便在运行任何初始化程序之前配置gem。
有没有人看到我失踪的东西?有没有办法让gem在处理初始化程序后立即执行某些工作(但在Rails开始完成引导过程之前)?如果没有,似乎Rails有一个有用的钩子会在处理初始化器后立即触发。
答案 0 :(得分:2)
感谢@Raffael建议的链接,我能够提出一个解决方法。如果其他人遇到类似情况,app_middleware
可以保存当天。
我能够通过以下方式使用app_middleware注册OmniAuth中间件:
class Railtie < Rails::Railtie
config.before_initialize do
setup_proc = lambda do |env|
options = {
issuer: "foo",
# Other options ...
}
env['omniauth.strategy'].options.merge!(options)
end
config.app_middleware.use OmniAuth::Builder do
provider :saml, :setup => setup_proc
end
end
end
这有助于解决我遇到的初始化顺序。