Ecto-ассоциация с условием

Скажем, у меня две модели: Post и Comment, а модель комментариев может быть 1 из 2 типов, normal и fancy, которая определяется столбцом type в comments Таблица.

Теперь я хочу добавить 2 ассоциации в мою модель Post, где один относится к причудливым комментариям и к обычным, как мне это сделать? Поэтому я хочу что-то вроде этого:

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

Ответ 1

Это не доступно в Ecto, об этом подробно обсуждается на этой проблеме GitHub.

Для этого можно использовать запрограммированный запрос:

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()

Вот сообщение в блоге о составных запросах.

Вы также можете использовать предварительную загрузку с запросом:

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