Queries within Repo.preload to return single items instead of lists


I’ve been playing with using queries inside Repo.preload, and I was wondering if there is a way to have it return a result outside of a list if you know the result is not a collection.

I’ve been doing something like

from(u in User, where: u.user_id ==  ^user_id)
|> Repo.one
|> Repo.preload(posts: [responses: [likes: from(l in Like, where: l.user_id == ^user_id, limit: 1, select: l.value)

Considering that l.value is a boolean, here I receive things like [true] instead of true

Right now what I’m doing is to go through the result after it gets back from the database and map through it to Enum.at(0) those results.

I actually use Kernel.update_in which is sooo amazing for such nested data structures, but still, it feels like that should be handled in the query itself, I just don’t know how…

Any ideas?

Thank you!

I don’t quite understand your data model but considering the part you preload your query:

[responses: [likes: your_query]]

I think if you put it as [likes: query], does not this mean that you’re expecting a list of likes?

Instead of that, maybe what you want is the following?

[responses: your_query]
1 Like

So the idea is that :responses field would refer to a struct that contain many fields being :likes one of them. Then :likes in its turn would refer to yet another struct, but I’d want only one field (in this example :value).

As I understand I’d have to put them in square brackets to achieve this hierarchy of preloads, but that wouldn’t mean a list… isn’t that right?

1 Like

Oh my bad, that’s right.

I think what you get as results depends on the way you define your schemas associations. A has_many :likes will result in a list when preloading, a has_one :like a struct, a belongs_to :parent also a struct.

Maybe could you achieve what you want with select_merge.
But you’ll have to use it on the main query, not on the preload.

select_merge cannot be used to set fields in associations, as associations are always loaded later, overriding any previous value.

1 Like

Ohhh! You are exactly right!

I had has_many relationship for them cause I was thinking of the schemas generally as opposed to their “instances”. I would have NEVER, in a million years have considered that. Thank you so much!!

1 Like