多态关联如何与 Ecto 一起工作?
Posted
技术标签:
【中文标题】多态关联如何与 Ecto 一起工作?【英文标题】:How does Polymorphic association work with Ecto? 【发布时间】:2015-05-16 06:17:52 【问题描述】:当我阅读https://github.com/elixir-lang/ecto/issues/389 及其相关问题时,Ecto 似乎支持多态关联。
假设我需要一个关于任务和事件模型的评论模型关联。如果我对 Ecto 与自定义源关联的理解是正确的,那么我们需要四个表和三个模型,
表格
任务 事件 tasks_cmets events_cmets型号
任务 事件 评论任务和事件模型将与自定义源具有 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 关联?
【问题讨论】:
【参考方案1】:如果你使用上面的设计,评论模型实际上没有任何表,它的表是由关联定义的。因此,要获取所有事件的所有 cmets,您可以这样做:
from c in "events_comments", Comment
在某些情况下这是一项很棒的技术,它允许您不将存储(表)与模型耦合。您可以对不同的表使用相同的模型。
但是,如果您想获取所有 cmets 并将它们与事件和任务相关联,那么您可以使用 through 关系。您将拥有“events”“events_cmets”“cmets”和“tasks”“tasks_cmets”“cmets”。
另一种方法是使用 Rails 进行多态关联的方式,并在 Comment 模型中定义一个“种类”列。它确实会破坏数据库引用,但这是解决此问题的另一种方法。
我会就此事改进 Ecto 文档,感谢您的反馈!
【讨论】:
何塞,感谢您的回答。您的回答引发了多个问题。也许这一切都是微不足道的。 1.“评论模型实际上没有任何表”=>评论模型如何在没有模式的情况下工作。我正在阅读“模式 == 表”。如何在没有模式的情况下验证 Comment,从而没有变更集? 2. 'rails way' 在 Ecto 协会中是如何运作的?有没有示例代码?我没有看到支持此功能的源代码或文档。 1.评论模型没有表格,但通过关联构建时有表格。所以秘诀是使用assoc(task, :comments)
,而不是%Comment
。我在这里记录了这些:github.com/elixir-lang/ecto/commit/…
2. rails 方式在 Ecto 关联中不起作用,因为它通常是不好的做法,因为数据库无法保留其引用。您必须手动构建查询并设置正确的字段。
我还有一些相关的问题,但在提问之前我需要做一些功课。我可能会将其发布在邮件列表上,因为它可能更多的是意见而不是客观答案。谢谢你,何塞。
对于关注这个问题的人,后续帖子在这里:groups.google.com/forum/#!topic/elixir-ecto/mldnA3qx6Ak以上是关于多态关联如何与 Ecto 一起工作?的主要内容,如果未能解决你的问题,请参考以下文章