STI和多晶型物

我的代码有问题

class Post < ActiveRecord::Base end class NewsArticle  :commentable, :dependent => :destroy, :order => 'created_at' end class Comment  true, :counter_cache => true end 

并尝试去获取一些NewsArticle的评论,我在日志中看到类似的东西

  Comment Load (0.9ms) SELECT "comments".* FROM "comments" WHERE ("comments"."commentable_id" = 1 and "comments"."commentable_type" = 'Post') ORDER BY created_at 

奇怪的是“commentable_type”=“发布” 。 怎么了?

PS:Rails 2.3.5 && ruby​​ 1.8.7(2010-01-10 patchlevel 249)[i686-darwin10]

commentable_type字段需要存储包含数据的表的名称,一旦从右表加载该行,inheritance的类型将从Posts表的类型列加载。

所以:

这里的评论指向它所评论的表格。 post表,id 1

 >> Comment.first => # 

然后加载NewsArticle,从post加载id 1,其中的类型表示一个NewsArticle。

 >> Comment.first.commentable => # >> Comment.first.commentable.class.table_name => "posts" 

如果commentable_type持有"NewsArticle"则必须查看该类以确定该表。 通过这种方式,它可以只看到桌子,并在它到达那里后担心类型。

看一下ActiveRecord :: Associations API的Polymorphic Associations部分。 将多态关联与单表inheritance结合使用有一点点。 按照该部分中的第二个代码示例,我认为这可能接近您想要的

 class Comment < ActiveRecord::Base belongs_to :commentable, :polymorphic => true, :counter_cache => true def commentable_type=(sType) super(sType.to_s.classify.constantize.base_class.to_s) end end class Post < ActiveRecord::Base has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at' end class NewsArticle < Post end 

def commentable_type =(sType)super(sType.to_s.classify.constantize.base_class.to_s)end

此方法将类作为Post返回,如果要将inheritance的类Post存储为commentable_type,该怎么办?

好问题。 我使用Rails 3.1时遇到了完全相同的问题。 看起来问题还没有解决。 显然,在Rails中结合使用多表关联和单表inheritance(STI)有点复杂。

Rails 3.2的当前Rails文档提供了结合多态关联和STI的建议 :

将多态关联与单表inheritance(STI)结合使用有点棘手。 为了使关联按预期工作,请确保将STI模型的基本模型存储在多态关联的类型列中。

在您的情况下,基本模型将是“Post”,即“commentable_type”应该是所有注释的“Post”。

从技术上讲,这实际上并没有错。 当Rails处理多态关联,并且关联的对象使用STI时,它只使用基类作为类型(在您的情况下为“commentable_type”)。

如果你在单独的表中有Post和NewsArticle,很明显,commentable_type将分别显示为Post和NewsArticle。