ActiveRecord::Base#find 在单表继承 (STI) 中不返回任何记录
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于 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.