STI和多晶型物

时间:2010-04-08 21:31:20

标签: ruby-on-rails activerecord polymorphic-associations single-table-inheritance

我的代码有问题

class Post < ActiveRecord::Base
end

class NewsArticle < Post
  has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at'
end

class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true, :counter_cache => true
end

在尝试时,我会在日志中看到一些类似

的新闻文章
  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&amp;&amp; ruby 1.8.7(2010-01-10 patchlevel 249)[i686-darwin10]

5 个答案:

答案 0 :(得分:5)

commentable_type 字段需要存储包含数据的表的名称,一旦从右表加载该行,继承的类型将从类型加载帖子表格中的strong>列。

所以:

此处评论指向其评论的表格。帖子表,id 1

>> Comment.first
=> #<Comment id: 1, commentable_id: 1, commentable_type: "Post", body: "test", created_at: "2010-04-09 00:56:36", updated_at: "2010-04-09 00:56:36">

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

>> Comment.first.commentable
=> #<NewsArticle id: 1, type: "NewsArticle", name: "one", body: "body", created_at: "2010-04-09 00:55:35", updated_at: "2010-04-09 00:55:35">
>> Comment.first.commentable.class.table_name
=> "posts"

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

def commentable_type =(sType)    超(sType.to_s.classify.constantize.base_class.to_s)   端

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

答案 3 :(得分:1)

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

Rails 3.2的当前Rails文档提供了组合polymorphic associations and STI

的建议
  

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

在您的情况下,基本模型将是“Post”,即“commentable_type”应为所有评论的“Post”。

答案 4 :(得分:0)

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

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