How to Query a User with has_many Post in Ecto

def get_all_post_by_user(user_id) do
  query = from u in User,
     where: u.id == ^user_id,
      join: p in Post, on: p.user_id == u.id,
      select: %{
          user_id: u.id,
          username: u.username,
           title: p.title,
           description: p.description
      }
   query |> Repo.all
end

i have this query but when i try to render it, it returns multiple set of data but same User with different Post.
like this.
[

              %{user_id: 1,
              username: "saint",
               title: "test1",
               description: "sample1"},

              %{user_id: 1,
              username: "saint",
               title: "test2",
               description: "sample2"}
]

Thanks in advance.

1 Like

You have a typo in the query. Should probably be where: u.id == ^user_id.

I think that’s how table joins work. In psql you would get multiple rows. Maybe try Repo.preload or Ecto.Query.preload.

3 Likes

Sorry for the typo and thanks for the quick response, ahm. i try to avoid using preload because of this https://medium.com/@alves.lcs/phoenix-ecto-preload-can-be-evil-96f877fb52f5. is it true? thanks

is it true?

It might be. Depends on the amount of data that you query.

A join or Ecto.Query.preload might be evil as well since then ecto would have to parse multiple almost identical rows like in your example and then put them all into some “parent” struct. Repo.preload, which fires a second query, might be more efficient in that case.

1 Like

Okay thanks sir for the info :slight_smile:

Can someone post an example of how to use preload to achieve this? I’m very new and haven’t wrapped my mind around it yet.

There are different ways to use it. I think it’s best to check out the documentation:

https://hexdocs.pm/ecto/Ecto.Query.html#preload/3

Best regards

Already tried with the examples in documentation, all ended with Ecto.QueryErrors.

Oh…

Can you share more details of what you are trying to do?

1 Like

Welcome! We’re happy to help. In order for that to be possible though, it’s important that you provide full and complete information showing the code you tried, and the errors you got.

2 Likes