Ecto 与条件的关联

Ecto association with a condition

假设我有两个模型,PostComment,评论模型可以是 2 种类型中的一种,normalfancycomments table 中的 type 列。

现在我想在我的 Post 模型上添加 2 个关联,其中一个是花哨的评论,一个是普通评论,我该怎么做?所以我想要这样的东西:

has_many :fancy_comments, MyApp.Comment, where: [type: 0]
has_many :normal_comments, MyApp.Comment, where: [type: 1]

直到最近,这在 Ecto 中才可用。这个问题的另一个答案提供了当前的详细信息。关于如何添加它进行了长时间的讨论 this GitHub issue

在旧版本的 Ecto 中,您可以为此使用可组合查询:

defmodule MyApp.Comment do
  
  ...schema, etc.

  def fancy(query) do
    from c in query,
      where: type == 0
  end

  def normal(query) do
    from c in query,
      where: type == 1
  end    
end

然后您可以使用 has_many :comments, MyApp.Comment 并基于此进行查询:

assoc(post, :comments) |> Comment.fancy() |> Repo.all()

这是一篇关于 composable queries 的博客 post。

您还可以使用带有查询的预加载:

fancy_query = from(c in Comments, where: type == 0)
Repo.preload(post, comments: fancy_query)

现在可以在 Ecto 中使用条件关联:https://hexdocs.pm/ecto/Ecto.Schema.html#has_many/3-filtering-associations

defmodule Post do
  use Ecto.Schema

  schema "posts" do
    has_many :public_comments, Comment, where: [public: true]
  end
end