I have a data model that is deeply nested (3 - 5 levels deep).
Using ecto, I have the schema setup so that the associations are established amongst each of the relevant entities.
I have a query where I want to update this object. Normally I’d load the object, push it through a changeset, and then send the update. In this case, because the parent is so nested, I’d prefer the parent query to be ignorant of the nested tables within the children.
Is there a way to tell preloaded objects to preload all of their fields? The only examples I can find are where the parent explicitly declares all child preload items - instead, I’d prefer the children to know how to load themselves, and report that back to the parent. Is this a possibility?
You can use the preload query binding to create a preloaded query that you then use with Repo.one.
nested_assocs = # your nested structure
Repo.one(from p in Program, where: p.id == ^program_id, preload: ^nested_assocs)
The nested structure is a keyword list where you can specify all the levels of nesting you require. e.g. [events: [child_1: [:sub_child2]], phases: [:other_nesting]] if your event has a nested child_1, which itself has a nested sub_child2, etc.
From the documentation:
# Returns all posts, their associated comments, and the associated
# likes for those comments.
from(p in Post,
preload: [comments: :likes],
I think this development of a nested key structure is probably the route I should take.
Context for my use case is that I am implementing a graphql API. There is a graphql mutation which is passing deeply nested form state. I need to load the pieces of the mutation that are in the update, so that I can run the object through a changeset and save.
If it also says Use ^ on the outermost preload to interpolate a value then you should interpolate the preloaded_keys variable, like Repo.one(..., preload: ^preloaded_keys)
Please share the code and full error message, that will help to debug.
Otherwise try the other suggestions to reduce, but I’m in favour of the preload query expression because ecto should only use the connection pool once, instead of getting a new connection for every Repo.preload command.