2016-07-05 62 views
62

我已经将我的一个应用程序从Rails 4.2.6升级到了Rails 5.0.0。 Upgrade Guide表示,默认情况下,自动加载功能现在在生产中处于禁用状态。Rails 5:在生产中加载lib文件

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

module MyApp 
    class Application < Rails::Application 
     config.autoload_paths += %W(lib/) 
    end 
end 

现在,我已经设置了config.enable_dependency_loadingtrue,但我不知道是否有更好的解决了这一点。默认情况下,自动加载功能在生产中已被禁用。

+0

你有没有想出解决办法? – dkam

+0

疯狂的事情,文档仍然告诉你做auto_load。我很困惑生产环境中出现新的应用程序时出了什么问题。自从我开始学习Rails 5以来,我没有阅读迁移指南。我提出了一个文档问题,希望能够解决这个问题:https://github.com/rails/rails/issues/27268 – akostadinov

+0

令人惊讶的是,我在'lib'目录中有两个文件,一个文件很容易在运行时使用,但另一个文件需要手动:D – illusionist

回答

22

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

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

+4

如果你不想挖掘Github上的长篇讨论帖,你可以在这里找到蒸馏解释:http://collectiveidea.com/blog/archives/2016/07/22/solutions-to -potential-upgrade-problems-in-rails-5/ – Ernest

+3

我使用了'config.eager_load_paths <<“#{Rails.root}/lib”',这更符合推荐的rails应用程序结构。 – akostadinov

+1

将lib放在'app/lib'中是由rails成员推荐的 https://github.com/rails/rails/issues/13142#issuecomment-275549669 – eXa

90

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

  1. lib目录到app,因为里面的应用程序的所有代码自动加载在开发渴望加载在督促,最重要的是autoreloaded在开发过程中,每次进行更改时都不必重新启动服务器。
  2. 删除任何指向lib中您自己的类的require语句,因为如果它们的文件/目录命名正确,它们全部自动加载,并且如果留下require语句,它可能会中断自动重新加载。更多信息here
  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 } 
    
+2

那么现在如何使用'''lib'''文件夹呢?我的意思是将'''lib'''目录移动到'''app'''目录看起来有点像解决方法。 –

+1

'/ app/lib /'放置了一个文件/类,它不是自动加载的。在rails 5.1中测试,新项目 –

+7

值得注意的是,你需要停止弹簧。我把所有东西都移到了app/lib /,然后浪费了一些时间,想知道为什么我仍然无法从控制台使用我的类。春天停止ftw :) – jacklin

16

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

# config.autoload_paths << Rails.root.join('lib') 
config.eager_load_paths << Rails.root.join('lib') 

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

谢谢Johan建议您用Rails.root.join('lib')代替#{Rails.root}/lib

+1

工程就像一个魅力。我不喜欢语法,所以把它改成了'config.eager_load_paths << Rails.root.join('lib')'。 –

0

将lib文件夹移动到应用程序有助于解决问题,我的Twitter API不会在生产环境中运行。我有“未初始化的恒定TwitterApi”和我的Twitter API在我的lib文件夹中。 我在我的application.rb中有config.autoload_paths += Dir["#{Rails.root}/app/lib"],但在移动文件夹之前它不工作。

这奏效了

2

这使得有LIB自动重,并在生产环境中也起作用。

P.S.我已经改变了我的答案,现在增加了两个eager-自动加载路径,无论环境,允许自定义环境工作过(如舞台)

# config/initializers/load_lib.rb 
... 
config.eager_load_paths << Rails.root.join('lib') 
config.autoload_paths << Rails.root.join('lib') 
... 
+2

您能否介绍一下为什么解决了这个问题? –

+0

@ Stuart.Sklinar这允许lib自动重新加载,并且也可以在生产环境中工作。附:我已经改变了我的答案,现在它增加了两个热切的自动加载路径,无论环境如何,以允许在自定义环境中工作(如舞台) – bjornmelgaard

+0

您可以扩展(在您的答案)? 只有代码答案并不能真正帮助任何人理解为什么它应该以这种方式完成 - 我应该添加我不是Ruby开发人员,只是帮助清理SO。给“代码唯一答案”添加一些评论会给它一些实际的上下文。 –

相关问题