1-1多态关联是否有意义?

时间:2013-12-02 15:25:45

标签: ruby-on-rails-3 associations

我有两个模型,文章和文件。每个人都需要一个编辑器,即包含文章或文档的内容正文。多态关联是有道理的。

class Article < ActiveRecord::Base
  has_one :editor, :as => :editable
end

文档

class Document < ActiveRecord::Base
  has_one :editor, :as => :editable
end

编辑

class Editor < ActiveRecord::Base
  belongs_to :editable, :polymorphic => true
end

Editor模型包含以下属性:

content,editable_id,editable_type(模型名称,即文章或文档)

一切正常,但是我需要吗?

如果我希望访问给定文章的内容正文,我是否可以直接获取编辑字段的ID?

@article = Article.find(params[:id])
@editor_id = @article.editor.id

并执行我的编辑器查找。

在这种情况下,我没有看到一对一的多态关系的好处。谁能让我直截了当?

1 个答案:

答案 0 :(得分:1)

首先,针对你的具体问题,为什么你不能在没有多态关系的情况下做以下事情:

  

@article = Article.find(params [:id])

     

@editor_id = @ article.editor.id

@ article.editor.id工作的全部原因是因为多态关系。这有点像:

  • 你有一个has_one:编辑器,这意味着@ article.editor =这个编辑器模型基于它的可编辑字段
  • 现在您已经在这里找到了这个编辑器模型,它的ID是

如果您取出has_one,它将停止工作。此外,您根本不需要查找,因为这也是如此:

  

@article = Article.find(params [:id])

     

@editor = @ article.editor

不是更大的问题是,有没有办法设置它而不使用多态。

为了使事情变得尽可能简单,您可以将内容字段放在文档和文章中。如果:

,这将是有意义的
  • 您将始终使用内容字段,这样您就不会占用数据库空间

  • 没有特殊的代码,验证等与内容字段一起使用,然后会在两个地方重复。

我将假设您有一个编辑模型,该模型中有函数,验证等,要求它是自己的实体,以避免代码重复。此时您可以选择两条路线。第一个是通过将editor_id放在Article和Document中并使它们成为belongs_to:editor来避免多态。是的,你避免了多态行为,但你有一些严重的缺点:

  • 编辑器数据库表在多个位置引用,但表中没有任何内容可以告诉您谁正在使用哪个列。由于不得不经常“阅读”和“移植”数据库,所以我希望它是一个很好的未来考虑因素。 (如果您不使用多态,这不是问题,因为您会知道此表中的所有项目只能链接到另一个表。)

  • 每次要在模型中使用Editor时,都必须添加另一个迁移以将editor_id添加到该模型,并修改编辑器以使链接返回到该模型。 (从技术上讲,你可以跳过这一步,但为了代码可读性,你真的想要标记它可以链接到哪些模型。特别是如果你坚持做前一点。)

这样我们就可以回到原来的设置了。多态关系做了一些事情:

  • 在数据库中清楚说明每行属于哪个
  • 允许您使用代码而不是数据库更改来创建另一个模型和编辑器
  • 将特定于编辑器内容的所有功能保存在一个不错的位置

所以,是的,我认为一对一的多态有意义。它导致:   - 更容易维护的数据库   - 更容易添加未来的功能   - 更清晰的关系

我唯一要考虑的是,如果编辑器中几乎没有代码只是直接在文章和文档模型中转储字段并完全转储编辑器。