10

我的代码有问题

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" = 'Post'。怎么了?

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

4

5 回答 5

5

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

所以:

这里的注释指向它所评论的表。帖子表,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,从posts 中加载id 1,这里的type 表示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"它必须查看类来确定表。这样一来,它就可以只查看表格并担心到达那里的类型。

于 2010-04-09T01:04:20.380 回答
1

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

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

于 2010-12-16T14:33:12.603 回答
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
于 2010-04-09T21:17:22.173 回答
1

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

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

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

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

于 2012-05-30T16:53:15.380 回答
0

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

如果 Post 和 NewsArticle 在不同的表中,显然 commentable_type 将分别显示为 Post 和 NewsArticle。

于 2010-09-23T12:55:49.933 回答