Not sure if this is a hot take on ecto queries or not, but I always hated having to import Ecto.Query
into my modules. If I implement my own where/3
, then what. I don’t even know whether or not it works, but if it does, then how do I know which of the where
I am calling, without knowing which function heads are implemented by ecto, and which by the module. It makes me feel dirty.
So I like to keep ecto queries in their own modules, usually with queryable
as their first argument, so they can be piped. Calling Repo.all
would be a code smell to me, because maybe the query might be just a part of a composed query - executing it in the middle of creating a query feels very wrong. Like asking someone “could you write a query to get all these values” and they are like “sure”, select * from a; select * from b; select * from c;
“here you go!”
EDIT
To make clear what I mean:
def list_a_special_thing(opts \\ []) do
ThisContext.Schema
|> ThisContext.Queries.special_thing()
|> MyProject.Queries.with_opts(opts)
|> Repo.all()
end
where with_opts
implements some very generic cases like preloads
, limit
, etc.
ThisContext.Queries.special_thing
would still be usable in other queries, and list_a_special_thing
could be used like
all_of_the_special_things = ThisContext.list_a_special_thing()
# or
all_of_the_special_things = ThisContext.list_a_special_thing(preloads: @the_special_thing_preloads, limit: params["per_page"])