Rails:在具有警告的子文件夹中组织模型:顶级由B :: A引用的常量A.

ken*_*nko 17 ruby activerecord ruby-on-rails

今天我决定重新组织大量与用户相关的模型,我遇到了问题.

在我有这样的结构之前:

app/models/user.rb
app/models/user_info.rb
app/models/user_file.rb
...
Run Code Online (Sandbox Code Playgroud)

所以我将所有user_模型移动到用户子文件夹,如下所示:

app/models/user.rb
app/models/user/info.rb
app/models/user/file.rb
...
Run Code Online (Sandbox Code Playgroud)

并将其定义更改为

class User::Info < ActiveRecord::Base
class User::File < ActiveRecord::Base
...
Run Code Online (Sandbox Code Playgroud)

User 模型没有改变(协会除外).

除了User::File模特,一切都很好.当我试图访问此模型时,我收到以下错误:

warning: toplevel constant File referenced by User::File
Run Code Online (Sandbox Code Playgroud)

实际上它返回标准的ruby File类.

我做错了什么?

UPD1:

root# rails c
Loading development environment (Rails 3.2.13)
2.0.0p195 :001 > User::File
(irb):1: warning: toplevel constant File referenced by User::File
 => File
2.0.0p195 :002 > User::Info
 => User::Info(...)
Run Code Online (Sandbox Code Playgroud)

UPD2:

2.0.0p195 :001 > User::SomeModel
NameError: uninitialized constant User::SomeModel
2.0.0p195 :002 > User::IO
(irb):2: warning: toplevel constant IO referenced by User::IO
 => IO 
2.0.0p195 :003 > User::Kernel
(irb):3: warning: toplevel constant Kernel referenced by User::Kernel
 => Kernel 
Run Code Online (Sandbox Code Playgroud)

我的应用程序没有任何IO或内核类,除了ruby默认值.

UPD3:

# app/models/user.rb
class User < ActiveRecord::Base
  has_many :files, class_name: 'User::File'
  ..
end

# app/models/user/file.rb
class User::File < ActiveRecord::Base
  belongs_to :user
  # some validations, nothing serious
end
Run Code Online (Sandbox Code Playgroud)

tes*_*ssi 28

更新:今年圣诞礼物是Ruby 2.5.0的发布,不再发生此错误.使用Ruby 2.5+,您将获得所要求的常量或错误.对于较旧的Ruby版本,请阅读:

您的User::File课程未加载.你必须要求它(例如user.rb).

当ruby/rails查看User::Info并评估它时会发生以下情况(简化;仅User定义).

  • 检查是否User::Info已定义 - 它尚未(尚未)
  • 检查是否Info已定义 - 它尚未(尚未)
  • uninitialized constant- >做rails magic来查找user/info.rb文件并要求它
  • 返回 User::Info

现在让我们再做一次 User::File

  • 检查是否User::File已定义 - 它尚未(尚未)
  • 检查是否File已定义 - 它是(因为ruby有一个内置File类)!
  • 发出警告,因为我们被要求User::File但得到了::File
  • 返回 ::File

我们观察到rails魔法,它自动需要(尚未)常量的文件,但不起作用,User::File因为File它不是未知的.

  • 谢谢你的解释.在`user.rb`的顶部添加require会给我错误 - `/ app/models/user.rb:2:在`<top(required)>'中:User不是类(TypeError)`,但在文件末尾添加require可以解决问题. (2认同)