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

标签 ruby-on-rails ruby activerecord

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

在我有这样的结构之前:

app/models/user.rb
app/models/user_info.rb
app/models/user_file.rb
...

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

app/models/user.rb
app/models/user/info.rb
app/models/user/file.rb
...

并将它们的定义更改为

class User::Info < ActiveRecord::Base
class User::File < ActiveRecord::Base
...

User 模型未更改(关联除外)。

User::File 模型外,一切正常。当我尝试访问此模型时,出现以下错误:

warning: toplevel constant File referenced by User::File

实际上它返回标准的 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(...)

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 

我的应用没有任何 IO 或内核类,ruby default 除外。

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

最佳答案

更新:今年的圣诞礼物是 Ruby 2.5.0 的发布,这个错误不会再发生了。使用 Ruby 2.5+,你要么得到你要求的常量,要么得到一个错误。对于旧的 Ruby 版本,请继续阅读:

您的 User::File 类未加载。您必须要求它(例如在 user.rb 中)。

当 ruby​​/rails 看到 User::Info 并对其求值时会发生以下情况(简化;目前仅定义了 User)。

  • 检查 User::Info 是否已定义——(还)未定义
  • 检查 Info 是否已定义——(还)未定义
  • 未初始化的常量 -> 使用 rails 魔法找到 user/info.rb 文件并需要它
  • 返回用户::信息

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

  • 检查 User::File 是否已定义——(还)未定义
  • 检查是否定义了 File - 它是(因为 ruby​​ 有一个内置的 File 类)!
  • 产生警告,因为我们被要求输入 User::File 但得到的是 ::File
  • 返回::文件

我们观察到 Rails 的魔力,它自动需要文件来处理(还)未知的常量,但对 User::File 不起作用,因为 File 不是未知的。

关于ruby-on-rails - Rails:在具有警告的子文件夹中组织模型:B::A引用的顶级常量A,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17695557/

相关文章:

html - 使用大量 HTML 渲染页面

ruby-on-rails - 获取无效几何图形: LinearRing failed ring test after upgrading rgeo gem

ruby-on-rails - 按生产商名称对产品排序,否则按 "Rails way"中的其他内容排序

ruby-on-rails - 如何将数据库中缺少的参数字段合并到 rails 中的参数哈希

ruby-on-rails - 如何在 Rails 4.2 和 sqlite 中按星期几进行过滤?

ruby-on-rails - 访问 routes.rb 中的 URL 助手

ruby - 在 `Rack::Session::Pool` 上使用 `Rack::Session::Cookie`

ruby-on-rails - 通过rails has_many删除记录:through

php - Yii框架2.0 Active Record选择具有一定条件的记录

ruby-on-rails - Ruby on Rails 中的 link_to 机制如何工作