ActiveRecord::Base#find 在单表继承 (STI) 中不返回任何记录

发布于 2024-09-13 14:18:23 字数 1068 浏览 2 评论 0原文

app/models

class Amodel < ActiveRecord::Base
end

class Bmodel < Amodel
end

class Cmodel < Bmodel  
end

db/migrate

create_table :amodels do |t|
  t.string :type
end

on script/console...

$ script/console
Loading development environment (Rails 2.3.4)
>> Cmodel.create
=> #<Cmodel id: 1, type: "Cmodel">
>> Bmodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

好的,但是 Bmodel 在重新启动控制台后不会返回任何记录,例如:

>> exit
$ script/console
Loading development environment (Rails 2.3.4)
>> Bmodel.find(:all)
=> []

但是,它在访问 Cmodel 后可以工作:

>> Cmodel
=> Cmodel(id: integer, type: string)
>> Bmodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

Amodel 的工作方式如下:

>> exit
$ script/console
Loading development environment (Rails 2.3.4)
>> Amodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

有人知道为什么它会这样工作吗?

导轨:2.3.4
红宝石:1.8.7
操作系统:Ubuntu 9.0.4

app/models

class Amodel < ActiveRecord::Base
end

class Bmodel < Amodel
end

class Cmodel < Bmodel  
end

db/migrate

create_table :amodels do |t|
  t.string :type
end

on script/console...

$ script/console
Loading development environment (Rails 2.3.4)
>> Cmodel.create
=> #<Cmodel id: 1, type: "Cmodel">
>> Bmodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

ok, but Bmodel returns no records after rebooting console like:

>> exit
$ script/console
Loading development environment (Rails 2.3.4)
>> Bmodel.find(:all)
=> []

however, it works after accessing Cmodel:

>> Cmodel
=> Cmodel(id: integer, type: string)
>> Bmodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

Amodel works like:

>> exit
$ script/console
Loading development environment (Rails 2.3.4)
>> Amodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

Does anyone know why it works like this?

Rails: 2.3.4
Ruby: 1.8.7
OS: Ubuntu 9.0.4

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岛徒 2024-09-20 14:18:23

由于 ActiveRecord STI 的构建方式。加载类时,它会向其父类注册(请参阅 #inherited 钩子)。因此,当您调用 Amodel#find 或 Bmodel#find 时,如果子类未知,则还无法找到它。

在生产中,这个问题不会很明显,因为Rails在启动时会加载所有模型,从而防止出现此类问题。

Because of the way ActiveRecord STI is built. When a class is loaded, it registers with it's parent (see the #inherited hook). Thus, when you call Amodel#find or Bmodel#find, if the subclass isn't known, it can't be found yet.

In production, this problem wouldn't be apparent, because Rails will load all models when it starts, preventing this kind of problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文