abdelaz3r

abdelaz3r

Load nested association and select count at the same time

Hello.

I have this Ecto Shema:

Instance -> has_many(Faction) -> many_to_many(Profils)

So, instances has many factions, and profils can register into a faction (given an instance).

I would like, when I load instances, to preload their corresponding factions (easy) and to add, for each faction, a field that is the number of registered profil.

First question: I dont know if I need to add a field (virtual?) to the faction schema (such as “registered_profils”).

Second question: How would look like the request?

For now I have this request that works (but it only preload factions into instances and profils into factions):

query =
  from instance in Instance,
    left_join: factions in assoc(instance, :factions),
    left_join: profils in assoc(factions, :profils),
    preload: [factions: {factions, profils: profils}],
    order_by: [desc: instance.id]

I also tried different queries such as:

query =
  from instance in Instance,
    left_join: factions in assoc(instance, :factions),
    left_join: profils in assoc(factions, :profils),
    preload: [factions: {factions, profils: profils}],
    group_by: factions.id,
    select: {factions.registered_profils, count(profils.id)},
    order_by: [desc: instance.id]

But none works for now. Any idea?

Most Liked

Kurisu

Kurisu

I did something similar sometime ago.
I used a virtual field for the count then make a querry like:

....,
select_merge: %{factions_count: count(factions.id)
....

So your query could look like:

query =
  from instance in Instance,
    left_join: factions in assoc(instance, :factions),
    left_join: profils in assoc(factions, :profils),
    preload: [factions: {factions, profils: profils}],
    order_by: [desc: instance.id],
    select_merge: %{registered_profils: count(profils.id)

But to be honest I don’t know if this is the best way but it works. ^^

abdelaz3r

abdelaz3r

Ok, thanks a lot. It doesn’t work, but I think I undestand better :wink:

Now, the query looks like that:

query =
  from instance in Instance,
    left_join: factions in assoc(instance, :factions),
    left_join: registrations in assoc(factions, :registrations),
    preload: [factions: factions],
    select_merge: %{registrations_number: count(registrations.faction_id)},
    group_by: registrations.faction_id,
    order_by: [desc: instance.id]

And the real SQL query that ecto make is (after formatting):

SELECT
  i0."id",
  i0."game_data",
  i0."game_status",
  i0."metadata",
  i0."name",
  i0."opening_date",
  i0."status",
  i0."inserted_at",
  i0."updated_at",
  count(r2."faction_id"),
  f1."id",
  f1."capacity",
  f1."faction_ref",
  f1."instance_id",
  f1."inserted_at",
  f1."updated_at"
FROM "instances" AS i0
LEFT OUTER JOIN "factions" AS f1 ON f1."instance_id" = i0."id"
LEFT OUTER JOIN "registrations" AS r2 ON r2."faction_id" = f1."id"
WHERE ((i0."status" > 1))
GROUP BY r2."faction_id"
ORDER BY i0."id" DESC
LIMIT $1 OFFSET $2 [25, 0]

Note: I have plugins for custom filter and pagination, so the limit and the where clause come from that.

And I have this error : (Postgrex.Error) ERROR 42803 (grouping_error) column "i0.id" must appear in the GROUP BY clause or be used in an aggregate function.

I’m not sure if it’s the query that is not correct or if I need some subqueries to achieve that.

Note2: I changed a bit the schema since my first post. Instead of having a many_to_many relation between Factions and Profils, I created a real schema “registration” that belong_to Factions and Profils (I need to store other informations into registration).

abdelaz3r

abdelaz3r

Yep ok, but the thing is, you don’t load data from section, you only filter category by the section_id. I’m trying to list all sections (in your situation), with their corresponding categories AND the count of ads. Which is why Postegres is not very happy.

But thanks again for the help :wink:

I’m now looking on this topic : Ecto subqueries with virtual fields? - #9 by xadhoom which may help me eventually.

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New

We're in Beta

About us Mission Statement