名称错误:在Heroku上未初始化常量

5

我有一个Rails 5应用程序,其中一些模块/类位于/lib下。在开发过程中,我可以通过rails控制台访问这些模块/类,如下所示:

irb(main):001:0> MyClass.do_something

在Heroku生产环境中,我看到了这个错误信息:
irb(main):001:0> MyClass.do_something
NameError: uninitialized constant MyClass

你可能已经猜到了,我在我的application.rb文件中自动加载/lib目录:

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

然而,最让人好奇的是,我可以从rake任务中访问这个类。所以像这样的东西完全可以正常工作:
task do_something: :environment do
  MyClass.do_something
end

这告诉我该类在Heroku上存在。

有任何想法吗?


1
MyClass 运行正常 - 但是在你的 Rails 应用程序之外... - user4932805
@LiroyLeshed 好的,但这并不能解释为什么它在开发控制台中运行而在Heroku控制台中却不运行... - Severin
如果您在本地运行 rails c production 并尝试调用您的类,会发生什么? - nattfodd
@nattfodd,和在Heroku上一样的错误。你知道问题出在哪里吗? - Severin
2个回答

9
Rails不会在生产环境中自动加载线程安全性,而是急切地加载应用程序常量。您可以通过使用eager_load_paths方法来解决问题。
config.eager_load_paths << Rails.root.join('lib')

如果您仍希望在开发中自动加载,可以进行条件设置。
load_path_strategy = Rails.env.production? ? :eager_load_paths : :autoload_paths
config.public_send(load_path_strategy) << Rails.root.join('lib')

如果您在生产中确实需要此目录的自动加载,您可以将enable_dependency_loading设置为true
config.enable_dependency_loading = true
config.autoload_paths << Rails.root.join('lib')

请参考这篇博客文章获取更详细的解释。

2
非常感谢,正是我所需要的。 - Severin

0

我一直很困惑为什么在Heroku生产环境的控制台中所有对象都是未初始化常量。在我的本地生产环境中,它们都运行正常。

事实证明,问题出在我使用了"heroku run console"而不是"heroku run rails console"。

值得注意的是,当您从Heroku网站访问控制台时,同样会出现这个问题。我为此浪费了很多时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接