控制Rails初始化程序加载顺序(可能需要新的Rails初始化挂钩)

时间:2015-12-23 22:34:13

标签: ruby-on-rails ruby-on-rails-4 rails-engines railtie

我正在构建一个使用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有一个有用的钩子会在处理初始化器后立即触发。

1 个答案:

答案 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

这有助于解决我遇到的初始化顺序。