Ecto中的双向关系和多态关联

问题描述 投票:0回答:1

我有一个名为:issues的表,我需要建立一种链接两个问题的方法。我曾考虑过创建一个名为:links的新表,但是由于必须遵循的规则,在设计Ecto模式时遇到了一些麻烦:

1. Links should be two-way and be any of these types: ["blocked-by" | "blocking" | "relates-to"]
2. If Issue-A is blocked-by Issue-B, Issue-B should be blocking Issue-A
3. If Issue-A relates-to Issue-B, Issue-B should relates-to Issue-A 
4. Creating a link on one issue should create a link on the linked issue, following rules 1 and 2.

使这进一步复杂的是其他表:stories:notes:milestones的存在,因为我应该能够将一个表中的记录与另一个表中的记录或具有相同规则的同一个表中的记录链接起来以上。

我还考虑过为每种类型的链接创建一个表。例如,Issue的更新模式将如下所示:

defmodule MyApplication.Issue do
  use Ecto.Schema

  @primary_key false
  schema "issues" do
    field(:issue_id, Ecto.UUID, primary_key: true)
    has_many(:linked_issues, LinkedIssue)
    has_many(:linked_stories, LinkedStory)
    has_many(:linked_notes, LinkedNote)
    has_many(:linked_milestones, LinkedMilestone)
  end
end

并且我必须对StoryNoteMilestone做同样的事情。我只是对如何设置迁移和引用感到困惑。我也不确定联接表如何知道哪个表正在链接它们,以及如何按照上述第四条规则双向建立关系。

elixir ecto polymorphic-associations
1个回答
0
投票

例如,双向链接可以简单地建模为2个单向链接。在这种情况下,要增强数据完整性,您将不得不依赖应用程序级逻辑或数据库触发器(后者更加安全,但维护成本更高)。

这里需要的多态性是一个棘手的问题。 Ecto不像Rails的ActiveRecord(和类似框架)那样支持多态关联。有意地,因为它要付出代价:打破FK约束(结果数据完整性较弱)和一些性能损失(乍看之下可以忽略不计,但随着数据库的增长而受到损害)。

至少有3种Ecto“建议”的解决方案:

  1. 单个links表,多个外键。
  2. 具有<object>_links本身的所谓抽象架构的多个Link
  3. 具有多个多对多联接表(linksissues_links,...)的单个milestones_links表]

每个都有很多优点和缺点,某些查询是特定的,等等。

[我建议参考https://pragprog.com/book/wmecto/programming-ecto-本书包含整章(14),详细说明了该问题以及上述所有可能的解决方案。假装是我自己的知识,只是在此处复制粘贴是不公平的:)

© www.soinside.com 2019 - 2024. All rights reserved.