多态关联如何与 Ecto 一起工作?

How does Polymorphic association work with Ecto?

Ecto 似乎支持多态关联,因为我通读了 https://github.com/elixir-lang/ecto/issues/389 及其链接的相关问题。

假设我需要一个关于任务和事件模型的评论模型关联。如果我对 Ecto 与自定义源关联的理解是正确的,那么我们需要四个 table 和三个模型,

表格

型号

任务和事件模型将具有 has_many 与自定义源的关联,如下所示。

defmodule ExampleApp.Task do
  use ExampleApp.Web, :model

  schema "tasks" do
    field :title, :string
    field :body, :string
    has_many :comments, {"tasks_comments", Comment}

    timestamps
  end
end

defmodule ExampleApp.Event do
  use ExampleApp.Web, :model

  schema "events" do
    field :title, :string
    field :body, :string
    has_many :comments, {"events_comments", Comment}

    timestamps
  end
end

现在我不明白的是评论模型应该是什么样子的?

Comment 模型如何处理两个 table?以及它如何处理 belongs_to 与不同模型的关联?

如果按照上面的设计,评论模型实际上没有任何table,它的table是由关联定义的。所以要获得所有事件的所有评论,你可以这样做:

from c in {"events_comments", Comment}

在某些情况下,这是一项很棒的技术,它允许您不将存储(table)与模型耦合。您可以对不同的 table 使用相同的模型。

但是,如果您想获取所有评论并将它们与事件和任务相关联,那么您可以使用 through 关系。您将有 "events" <-> "events_comments" <-> "comments" 和 "tasks" <-> "tasks_comments" <-> "comments".

另一种方法是使用 Rails 进行多态关联的方式,并在 Comment 模型中定义一个 "kind" 列。它确实破坏了数据库引用,但它是解决这个问题的另一种方法。

我会改进 Ecto 文档,感谢您的反馈!