Preload nested association table data

Hi,

I’m stuck with this problem for almost a month now. I posted this question on stack overflow.

I’ll copy/paste my post from stack overflow and edit the part where I made a progress.

So I have a schema model that look like this.

USER => MEETING <= PROJECT
uuid | user_uuid  | 
     | project_id |  id
          hour

I want to render in json, an object like this:

{
  uuid:"",
  first_name:"",
  project: [
    {
      name:""
      meeting: [
         hour:""
      ]
    }
  ]
}

So a single user has many (many_to_many in this case) project and a project has many (many_to_many also) user.

I also added a relation between project and meeting, because i want to render the meeting’s data inside the project, my ‘project’ schema relation:

many_to_many :user, User, join_through: Meeting, join_keys: 
[project_id: :id, user_uuid: :uuid]
has_many :meeting, Meeting

The problem is that when I preload my data I get the correct project for the user but I get all the meeting for the project even if the user is not part of it.

So in the question I posted on stack overflow, someone gave me this query, it looks great and I tought I had the answer, but I get exactly the same data:

def with_project_meetings(query) do
  from u in query,
      join: p in assoc(u, :projects),
      join: m in assoc(u, :meetings), on: m.user_uuid == u.uuid,
      preload: [projects: {p, meetings: m}]
end

Thanks

Shouldn’t the :on have to be :where here? Please tell if it still doesn’t work.

Your preload should use a function / another query.
Not sure if this will work for you, but to achieve the same result I have done something like this…

Also not sure what was in the query you were passing to compose, but simplified that a bit also to demonstrate.

def with_project_meetings(uuid) do
  from u in User,
      where: u.id == ^uuid,
      join: p in assoc(u, :projects),
      join: m in assoc(u, :meetings),
      preload: [projects: {p, meetings: ^user_meetings(uuid)}]
end

defp user_meetings(uuid) do
 from m in Meeting,
   where: m.user_uuid == ^uuid
end