18

当我阅读https://github.com/elixir-lang/ecto/issues/389及其相关问题时,Ecto 似乎支持多态关联。

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

  • 任务
  • 事件
  • 任务评论
  • events_comments

模型

  • 任务
  • 事件
  • 评论

任务和事件模型将具有与自定义源的 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 模型应该是什么样子?

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

4

1 回答 1

20

如果您使用上面的设计,评论模型实际上没有任何表,它的表是由关联定义的。因此,要获取所有事件的所有评论,您可以执行以下操作:

from c in {"events_comments", Comment}

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

但是,如果您想获取所有评论并将它们与事件和任务相关联,那么您可以使用 through 关系。您将拥有“事件”<->“事件评论”<->“评论”和“任务”<->“任务评论”<->“评论”。

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

我将改进有关此事的 Ecto 文档,感谢您的反馈!

于 2015-05-16T07:43:23.810 回答