【问题标题】:Does 1-1 polymorphic association make sense?1-1 多态关联有意义吗?
【发布时间】:2013-12-02 15:25:44
【问题描述】:

我有两个模型,文章和文档。每个都需要一个编辑器,即包含文章或文档的内容主体。多态关联是有意义的。

文章

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

然后执行我的编辑器查找。

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

【问题讨论】:

  • editable_id 不是唯一的......我希望你能在 SO 上提出愚蠢的问题!

标签: ruby-on-rails-3 associations


【解决方案1】:

首先,关于您为什么不能在没有多态关系的情况下执行以下操作的非常具体的问题:

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

@editor_id = @article.editor.id

@article.editor.id 起作用的全部原因是多态关系。它的内容如下:

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

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

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

@editor = @article.editor

对于更大的问题,是否有办法在完全不使用多态的情况下进行设置。

为了使事情尽可能简单,您可以将内容字段放在文档和文章中。如果满足以下条件,这将是有意义的:

  • 您将始终使用内容字段,因此您不会白白占用数据库空间

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

我将假设您有一个编辑器模型,该模型中的函数、验证等要求它是自己的实体以避免代码重复。在这一点上,你有两条路线可以走。第一种方法是通过将 editor_id 放在文章和文档中并使它们属于_to :editor 来避免多态。是的,你避免了多态行为,但你有一些严重的缺点:

  • Editor 数据库表在多个位置被引用,但表中没有任何内容可以告诉您谁在使用哪个列。不得不更频繁地“读取”和“移植”数据库,然后我想这是一个很好的未来考虑。 (在不使用多态性的情况下,这不是问题,因为您知道该表中的所有项目只能链接到另一个表。)

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

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

  • 在数据库中明确每一行属于谁
  • 让您可以让另一个模型拥有和编辑器,只需要代码而不是数据库更改
  • 将编辑器内容特有的所有功能集中在一个不错的位置

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

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

【讨论】:

  • 感谢您非常清晰的描述。是的,现在一切都说得通了。推动多态关系的主要原因是避免代码重复,你是对的,article.editor 仅因关联而起作用。感谢您花时间回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
相关资源
最近更新 更多