【问题标题】:How can I preload concerns in a rails initializer using Rails 6/Zeitwerk?如何使用 Rails 6/Zeitwerk 在 Rails 初始化程序中预加载关注点?
【发布时间】:2019-10-17 12:24:42
【问题描述】:

我正在使用一个初始化程序,它通过将一些应用程序关注点包含到第三方库中来对应用程序进行一些猴子修补。基本上:

# config/initializers/my_initializer.rb

class SomeExternalLib
  include MyConcern1
  include MyConcern2
end

这在 Rails 5.2.3 中运行良好,但在升级到 Rails 6 时收到以下弃用消息:

弃用警告:初始化自动加载常量 MyConcern1 和 MyConcern2。

不赞成这样做。初始化期间的自动加载正在进行 成为未来版本的 Rails 中的错误条件。

重新加载不会重新启动应用程序,因此在 初始化不再运行。因此,例如,如果您重新加载 ApplicationHelper, 预期的更改不会反映在该陈旧的 Module 对象中。

这些自动加载的常量已被卸载。

请查看“自动加载和重新加载常量”指南以获取解决方案。 (从 /Users/myuser/code/myapp/config/environment.rb:7 调用)

我担心的是 app/controllers/concerns/。经过一番调查,我发现该路径没有被自动加载,但我不知道如何使 Zeitwerk(Rails 6 的新自动加载器)动态加载它。我尝试遵循here 描述的 STI 自动加载模式,但没有运气。知道如何解决此弃用警告吗?

【问题讨论】:

    标签: ruby-on-rails ruby autoload ruby-on-rails-6


    【解决方案1】:

    正如@Glyoko 的回答所描述的,在依赖项上使用require 可以防止在初始化程序中自动加载。但是,正如@Puhlze 在他的评论中提到的那样,这样做会导致重新加载过程中出现问题。

    我偶然发现了一种在this post 中使用Rails.configuration.to_prepare 的替代方法。

    一个例子是:

    # config/initializers/my_initializer.rb
    
    Rails.configuration.to_prepare do
      class SomeExternalLib
        include MyConcern1
        include MyConcern2
      end
    end
    

    请注意,这在开发中的每个请求之前运行,但在生产中预加载之前只运行一次。

    编辑:它似乎也适用于重新加载。

    【讨论】:

    • 很不错的发现,风格上我更喜欢这个。这会保留代码重新加载吗?我的印象是问题的性质排除了在初始化程序中重新加载代码。
    • 它似乎适用于重新加载 - 已编辑以包含这一点!
    【解决方案2】:

    如果我更仔细地阅读错误消息会有所帮助:

    在未来的 Rails 版本中,初始化期间的自动加载将成为错误条件。

    更改的讨论是here,指南是here

    简而言之,自动加载不应该在初始化程序中完成,这将被逐步淘汰。解决方案是:1)不要使用需要在初始化程序中自动加载的东西(显然是首选),或者 2)在初始化程序中明确需要依赖项。

    所以我会这样做:

    # config/initializers/my_initializer.rb
    
    require 'my_concern1'
    require 'my_concern2'
    
    class SomeExternalLib
      include MyConcern1
      include MyConcern2
    end
    

    【讨论】:

    • 使用 'require' 的问题是它会破坏所需文件中的代码重新加载。不幸的是,似乎没有更好的选择来保持代码重新加载。
    猜你喜欢
    • 1970-01-01
    • 2021-05-31
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    相关资源
    最近更新 更多