I'm using Ecto to request data from the database, and I've used the following code to preload the cats filtered by price_discount.
Item
|> join(:inner, [i], c in Cat, c.food_category_id == i.id)
|> where([i, c], is_nil(c.price_discount))
|> preload([i, c],
[
cats: c,
cats: :houses
])
This works great, but now I want to order Houses by id, so I was hopping this work:
Item
|> join(:inner, [i], c in Cat, c.food_category_id == i.id)
|> where([i, c], is_nil(c.price_discount))
|> preload([i, c],
[
cats: c,
cats: [
houses: from(h in Houses, order_by: h.id)
]
])
But it doesn't, this is the error:
from(h in Houses, order_by: h.id()) is not a valid preload expression. preload expects an atom, a list of atoms or a keyword list with more preloads as values. Use ^ on the outermost preload to interpolate a value
The only post to work is to just use one of the following:
cats: c
without the orderhouses: from(h in Houses, order_by: h.id)
The following works, using ^:
Item
|> join(:inner, [i], c in Cat, c.food_category_id == i.id)
|> where([i, c], is_nil(c.price_discount))
|> preload([i, c],
^[
cats: [
houses: from(h in Houses, order_by: h.id)
]
])
Is this a bug in Ecto ?
When you want to provide a custom query to a preload and also to its nested preloads, you can use the tuple syntax, where the first element is the main query and the second element is a list of preloads just like you'd have at the top level.
What you want can be achieved with this:
|> preload([i, c], [cats: {c, houses: ^from(h in Houses, order_by: h.id)}])
The solution that I found was to split |> preload() in two.
Item
|> join(:inner, [i], c in Cat, c.food_category_id == i.id)
|> where([i, c], is_nil(c.price_discount))
|> preload([i, c], [cats: c])
|> preload([cats: [houses: from(h in Houses, order_by: h.id)]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With