Rails: 名称错误:未初始化的常量

59

我有一个叫做PhoneNumber的简单模型:

class PhoneNumber < ActiveRecord::Base
  validates :pnumber, presence: true, on: :create #=> { :message => " cannot be blank" }
  validates :pnumber, numericality: true, on: :create
end

我进入应用程序的根文件夹(其中包含app子文件夹),并启动控制台:

rails console --sandbox

当我尝试创建一个空的电话号码(我希望由于验证失败而收到错误消息)时,我会收到以下错误消息:

2.0.0-p451 :001 > PhoneNumber.new
NameError: uninitialized constant PhoneNumber
from (irb):1
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/commands/console.rb:90:in `start'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/commands/console.rb:9:in `start'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/commands/commands_tasks.rb:69:in `console'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/commands.rb:17:in `<top (required)>'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/app_rails_loader.rb:43:in `require'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/app_rails_loader.rb:43:in `block in exec_app_rails'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/app_rails_loader.rb:32:in `loop'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/app_rails_loader.rb:32:in `exec_app_rails'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/lib/rails/cli.rb:5:in `<top (required)>'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/bin/rails:9:in `require'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/railties-4.1.5/bin/rails:9:in `<top (required)>'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/bin/rails:23:in `load'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/bin/rails:23:in `<main>'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/bin/ruby_executable_hooks:15:in `eval'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/bin/2.2.2.02.02.02.0.2.2.02.222222.2.02.02.0.2.2.022222222222222

看起来控制台不知道这个模型。在纯 Ruby 中,您需要“require”包含类的文件,但我认为 Rails 控制台应该自动加载所有模型。这里出了什么问题?


1
为了修复这个问题,我只需要在迁移文件名中将模型名称变成复数形式,例如:20180612create_users.rb - fungusanthrax
17个回答

76

有一些尝试的方法:

  1. 重新启动Rails控制台;如果您不执行> reload!(尽管我发现这很难预测),或者重新启动控制台,那么对模型的更改只会被已经打开的Rails控制台捕获。

  2. 您的模型文件名是否为"phone_number.rb",并且是否在"/app/models"目录下?

  3. 您应该仔细检查Rails控制台命令中的“--sandbox”选项。据我所知,这可以防止更改。请尝试去掉此选项。


9
看起来这是文件的名称——它是app/models/PhoneNumber.rb。当我将其更改为app/models/phone_number.rb时,错误信息消失了。 - Nick
1
“reload!”对我有用!看起来模型初始化的某些部分被缓存了,因此如果该部分存在错误,则在第二次运行控制台时可能会变成“不可见”错误。 - Meekohi
在我的情况下,模型名称是复数形式,我只需要更改它。谢谢。 - Olivier JM
我的问题通过重新启动Rails控制台得到了解决。 - Indika K
仅做补充; 我有一个名为PRH(首字母缩写)的模块,因此我需要将文件命名为p_r_h.rb才能使其正常工作。 - Kent Robin

31

我遇到了一个错误:

NameError: 未初始化的常量

后来我发现我不小心创建了一个复数模型,所以我回去把模型文件的名称改成单数,然后在模型文件中也将类名改为单数,问题就解决了。


29

我在将Rails 5.1升级到5.2后遇到了这个问题
我通过以下方式解决了它:

spring stop
spring binstub --all
spring start
rails s

8

我也遇到过直接存在models目录下的文件无法正常加载的问题,后来发现是我没有在启动时正确加载代码。我通过在development.rb文件中设置config.eager_load = true解决了这个问题。这样就可以在控制台中使用该类了。


2
以下是有关此解决方案的更多信息:http://collectiveidea.com/blog/archives/2016/07/22/solutions-to-potential-upgrade-problems-in-rails-5/ tldr; “在Rails 5中,如果config.eager_load = true,则自动加载现已完全禁用。” - lostphilosopher
目前正在将一个遗留项目从4.2升级到5.2(作为第一步),这解决了我们在CI中设置RAILS_EAGER_LOAD_CLASSES: true时遇到的NameError: Uninitialized Constant问题。谢谢大家! - wbt11a

5
如果以上方法都不起作用,我还有另一种方法,因为我在真实场景中遇到过这种情况。具体来说,使用从Thrift自动生成的Ruby文件。
在我的情况下,我有一个包含多个类的模块,所以在这种情况下顺序很重要类A在同一模块中使用类B。但是,类B类A之后声明。
简单地让类B类A之前声明就解决了我的问题。

5

我的问题也得到了解决,通过确保文件名与类名相同,并符合正确的约定。例如,class AdLikes 的文件名应为 ad_likes.rb


1
是的,这很重要。 - ispirett

4

与 @Michael-Neal 类似。

我已将控制器命名为单数形式。

app/controllers/product_controller.rb

当我将其重命名为复数形式时,错误得到了解决。

app/controllers/products_controller.rb


2
我在使用 Ubuntu 20.04 上开发一个 Rails 6 应用时遇到了同样的问题。
当我使用以下命令启动 Rails 控制台时:
rails console

然后运行以下命令列出所有可用的角色。

Role.all

我收到了以下错误:

Traceback (most recent call last):
        1: from (irb):2
NameError (uninitialized constant Role)

以下是我是如何解决问题的:

问题在于我的Role模型被命名空间为一个叫做Userbase的模块。所以应该改成这样:

Role.all

应该是这样的:

它应该是这样的:

Userbase::Role.all

那就这样了

希望这有所帮助


1
我遇到了这个问题,是因为我在模型中更改了类的名称,导致与文件名不匹配。
“模型类名称使用驼峰命名法。这些名称是单数形式,并将自动映射到复数形式的数据库表名称。
模型文件放在 app/models/#{singular_model_name}.rb 中。”

https://gist.github.com/iangreenleaf/b206d09c587e8fc6399e#model


0
这种类型的异常在Ruby on Rails中是非常常见的,但我刚好遇到了一个与常量(大写字母)和代码加载顺序有关的版本。
基本上,我有一个验证,它引用了一个在验证下面定义的常量,结果遇到了以下错误:
未初始化的常量Role::PERMISSIONS(NameError)
这让我困惑了几分钟,但我意识到问题所在,并通过将PERMISSIONS的定义移到引用它的验证上面来解决了这个问题。

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