如何创建具有多种类型的 has_many 关联?

5

我有以下内容:

  • 一个链接模型
  • 一个LinkItem模型,我希望它是以下类型之一
    • 评论
    • 标签
    • ...

我正在使用以下代码:

链接模型

class Link < ActiveRecord::Base  
  has_many :link_items  
end

链接项模型

class LinkItem < ActiveRecord::Base
  belongs_to :link
end

class Comment < LinkItem
end

class Tag < LinkItem
end

现在我不知道如何告诉Rails我的LinkItem模型应该是多态的。我已经阅读了Rails Guide on asociations和其他教程,但这些教程只描述了如何创建一个属于多个其他模型的belongs_to关联,而不是另一种方式。

所以我的问题是:
如何创建一个has_many关联,其中关联实例可以是不同类型的?或者创建单独的模型来处理评论、标签等,并将它们各自与我的Link模型关联起来是否更好?

编辑
实际上我的代码可以工作。
我尝试在我的数据库中使用'type'列(而不是'link_item_type'),Rails会自动使用它来保存/确定我的LinkItems的正确子类(感谢Wizard of Ogz的提示)
然而,我仍然无法在引用LinkItem之前访问LinkItem的子类。这是某种惰性加载吗?


那应该可以在不使关联多态化的情况下工作。你试过了吗? - Wizard of Ogz
我尝试过,但每当我尝试访问Tag类(Comment同样如此)时,都会出现“未初始化常量Tag”错误。一旦我创建了LinkItem的实例,Tag和Comment就变得可访问了。另外,我无法区分这些项,因为请求的LinkItem始终作为LinkItem的实例返回,而不是Tag或Comment的实例。 - whitecorps
嗯...应该将标签和评论实例化。当评估link.link_items时,应返回由任何组合的LinkItemCommentTag记录组成的数组。也许你正在测试的记录的“类型”列设置为NULL,在这种情况下,ActiveRecord将只将它们全部实例化为LinkItem - Wizard of Ogz
我的子类的正确输入操作完成了。当我请求 link.link_items 时,我得到了正如你所提到的那样的数组。我的错误是使用了 link_item_type 列而不仅仅是 type。@nicholaides 提到的指南在我的情况下有点误导,因为那里使用了前一种命名约定,即 imageable_type 而不是 type(请参见指南中的 CreatePictures < ActiveRecord::Migration)。但是,每当我在没有先调用 LinkItem 的情况下尝试访问 Tag 模型时,我仍然会得到 NameError: uninitialized constant Tag。这只发生在开发模式下。 - whitecorps
4个回答

2

不幸的是,这只是另一个属于(belongs_to)的例子。一个标签被分配给一个对象(属于),它可以是一篇文章或许多其他模型中的一个,这些模型可以有标签。我想要一个具有许多对象的对象,这些对象可以是标签、评论等。但正如我在上面的编辑中提到的,我的代码现在可以工作了。也许多态关联有点误导或者在我的情况下使用了错误的术语? - whitecorps

0

我刚刚处理了我认为是同样的问题。

我的模型文件名错误。我最初使用一个名称创建它(例如link_tag.rb),然后在不更改文件名的情况下即时更改类的名称(例如从LinkTag更改为Tag)。

当我正确地重命名文件时,它按预期工作。

总之,文件名需要与类名匹配。

我知道这篇文章有点旧了,但也许它会在将来帮助某个人!


0

这被称为多态关联。这里有一些文档


是的,这就是我所说的指南,但它只描述了如何使belongs_to关联成为多态的,而不是has_many - whitecorps
看一下第一个代码示例。第二个类使用“has_many…,:as =>…” - nicholaides
但是这个例子只使用了一个Picture模型,而没有使用它的几个子类,例如Photo < Picture,Thumbnail < Picture等等。@wizard-of-ogz已经提到了我需要创建的类型列,以使我的示例在没有任何:as、:polymorphic等情况下工作。不过还是非常感谢! - whitecorps

-1

我经常使用多态关联!

我会先观看这个RailsCast,然后再查看nicholaides建议的文档

它完美地解释了如何创建关联的两个方面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接