Rails 5:在生产中加载lib文件

Tob*_*ias 118 ruby-on-rails autoload ruby-on-rails-5

我已将我的一个应用程序从Rails 4.2.6升级到Rails 5.0.0.该升级指南说,是自动加载功能在生产中默认情况下禁用现在.

现在我总是在生产服务器上出错,因为我在application.rb文件中加载了所有带有自动加载的lib 文件.

module MyApp
    class Application < Rails::Application
        config.autoload_paths += %W( lib/ )
    end
end
Run Code Online (Sandbox Code Playgroud)

现在,我已经设定了config.enable_dependency_loading,true但我想知道是否有更好的解决方案.必须有一个原因,默认情况下在生产中禁用自动加载.

Lev*_*sky 150

移动到Rails 5后的更改列表:

  1. libDIR到app,因为里面的应用程序的所有代码被自动加载在开发和渴望加载在督促,最重要的是autoreloaded在发展,所以你不必重新启动每次更改时间服务器.
  2. 删除任何require指向您自己的类的语句,lib因为如果它们的文件/目录命名是正确的,它们都是自动加载的,并且如果您保留require语句,它可能会破坏自动加载.更多信息在这里
  3. 设置config.eager_load = true在所有环境中以查看代码在dev中急切地加载问题.
  4. 使用Rails.application.eager_load!带有螺纹打,以避免"循环依赖"的错误了.
  5. 如果您有任何ruby/rails扩展,那么将该代码保留在旧lib目录中并从初始化程序手动加载它们.这将确保在您可以依赖它的其他逻辑之前加载扩展:

    # config/initializers/extensions.rb
    Dir["#{Rails.root}/lib/ruby_ext/*.rb"].each { |file| require file }
    Dir["#{Rails.root}/lib/rails_ext/*.rb"].each { |file| require file }
    
    Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,你需要停止弹簧.我把所有东西都移到app/lib /然后浪费了一点时间,想知道为什么我仍然无法从控制台使用我的类.春天停止ftw :) (27认同)
  • 那么现在如何使用```lib```文件夹呢?我的意思是将```lib``` dir移动到```app```dir看起来有点像解决方法. (6认同)
  • 这可能有效,但不是最佳解决方案。文件夹结构也是语义的。“lib”中的东西与“app”目录中的东西相比,对项目的感知接近程度不同。其他几个答案都比这个好。 (3认同)
  • `/ app/lib /`放置了一个文件/类,它不是自动加载的.测试在轨道5.1,新项目 (2认同)

Mic*_*ski 70

我只是使用config.eager_load_paths而不是config.autoload_paths像github上的提及akostadinov评论:https: //github.com/rails/rails/issues/13142#issuecomment-275492070

# config.autoload_paths << Rails.root.join('lib')
config.eager_load_paths << Rails.root.join('lib')
Run Code Online (Sandbox Code Playgroud)

它适用于开发和生产环境.

感谢约翰的建议,以取代#{Rails.root}/libRails.root.join('lib')!

  • 奇迹般有效.我不喜欢语法,因此将其更改为`config.eager_load_paths << Rails.root.join('lib')`. (3认同)
  • 对我来说,这是最好的答案。我的项目从头开始在Rails 5.2上,并且/ lib文件夹仍然是在/ app文件夹之外创建的。我认为没有充分的理由来移动它。 (2认同)

Tob*_*ias 29

由于线程安全,在生产环境中禁用自动加载.感谢@Зелёный的链接.

我解决了这个问题,将lib文件存储在Github上推荐的目录中的lib文件夹中.文件夹中的每个文件夹都会自动由Rails加载.appapp

  • 如果您不想深入了解Github上的长篇讨论主题,可以在这里找到精算说明:http://collectiveidea.com/blog/archives/2016/07/22/solutions-to-potential-upgrade-problems-在护栏-5 / (6认同)
  • 我使用`config.eager_load_paths <<"#{Rails.root}/lib"`,这是更好的IMO,以遵循推荐的rails应用程序结构. (6认同)
  • 这完全破坏了`lib`的目的.我会等待招标或DHH加入.与此同时,我(个人)建议坚持@Lev Lukomsky的回答. (4认同)
  • rails 成员推荐将 lib 放在 `app/lib` 中 https://github.com/rails/rails/issues/13142#issuecomment-275549669 (2认同)

Зел*_*ный 20

必须有一个原因,默认情况下在生产中禁用自动加载.

这是一个关于这个问题的长期讨论.https://github.com/rails/rails/issues/13142

  • 尽管阅读时间较长,但这篇讨论是我所遇到的关于该主题的最佳信息来源。 (2认同)

srg*_*hma 12

这允许lib自动重载,也可以在生产环境中工作.

PS我已经改变了我的答案,现在它增加了两个渴望 - 自动加载路径,无论环境如何,以允许在自定义环境中工作(如阶段)

# config/initializers/load_lib.rb
...
config.eager_load_paths << Rails.root.join('lib')
config.autoload_paths << Rails.root.join('lib')
...
Run Code Online (Sandbox Code Playgroud)

  • 你能否解释为什么这个问题解决了? (2认同)

Jit*_*hor 9

只需将config/application.rb 文件中的config.autoload_paths更改为config.eager_load_paths 即可。因为在 rails 5 中,生产环境默认禁用自动加载。欲了解更多详情,请点击链接

 #config.autoload_paths << "#{Rails.root}/lib"
  config.eager_load_paths << Rails.root.join('lib')
Run Code Online (Sandbox Code Playgroud)

它适用于环境开发和生产。


poc*_*sov 5

从某种意义上说,这是 Rails 5 中的统一方法来集中 Eager 和 Autoload 配置,同时在配置 Eager 加载时添加所需的自动加载路径,否则将无法正常工作:

# config/application.rb
...
config.paths.add Rails.root.join('lib').to_s, eager_load: true

# as an example of autoload only config
config.paths.add Rails.root.join('domainpack').to_s, autoload: true
...
Run Code Online (Sandbox Code Playgroud)