Экто / Эликсир: вернуть первого ребенка из вложенной ассоциации - PullRequest
0 голосов
/ 02 июня 2018

У меня есть запрос Ecto, который почти есть, но не совсем!

Он возвращает все сообщения, связанные с данными чатами, - но я бы хотел вернуть только первое сообщение из каждого чата.

Я пытался поиграть с подзапросами и фрагментами, но, похоже, не могу понять это правильно.

Repo.one!(
  from(
    p in Post,
    where: p.id == ^id,
    join: c in assoc(p, :chats),
    join: y in assoc(c, :messages),
    preload: [chats: {c, messages: y}]
  )
)

`` `

1 Ответ

0 голосов
/ 08 июня 2018
defmacro last_message_id(chat_id) do
  quote do
    fragment("""
      (
        SELECT
          m.ID
        FROM
          MESSAGES m
        WHERE
          m.CHAT_ID = ?
        ORDER BY m.INSERTED_AT ASC
        LIMIT 1
      )
    """, unquote(chat_id))
  end
end

post = Repo.get(Post, id)

chats_with_last_message =
  post
  |> assoc(:chats)
  |> join(:inner, [c], m in Message, m.id == last_message_id(c.id)
  |> select([c, m], %{chat: c, message: m})
  |> Repo.all()

Хорошо, это должно помочь вам начать.Я использовал два запроса здесь, но можно поместить его в один, используя this .Также обратите внимание на объединение INNER, которое означает, что оно фильтрует чаты с теми, в которых есть хотя бы одно сообщение.

PS Я не проверял код, но даже если он не работает, вы получаетеидея.Кто-то, у кого больше времени, вероятно, отправит правильный ответ.

...