I’m looking for a way to extend an existing select
on an Ecto query. I’d like to wrap any existing select
inside a tuple such that we preserve the original selection while also selecting another set of fields.
My goal is to allow my keyset pagination library (Chunkr) to not only honor the fields already selected by the passed-in query but to also automatically select additional fields needed to generate a cursor. In practice, the fields selected by the original query and the additional fields selected by Chunkr may or may not overlap.
Effectively, what I’m looking to implement is a function in the spirit of:
def apply_select(query, cursor_fields) do
case query do
%{select: nil} ->
Ecto.Query.select(query, [record], {cursor_fields, record})
%{select: existing_select} ->
Ecto.Query.select(query, _, {cursor_fields, existing_select})
end
end
That example won’t work, mostly because the :select
field on an Ecto.Query (i.e. the existing_select
above) is an Ecto-specific implementation detail—it’s not the raw select as provided by the original creator of the query.
For what it’s worth, I believe I could do what I need via select_merge
, but only if I force users of my library to always use a map for the top-level of their select. I’d prefer to more elegantly enable “any” Ecto query to be paginated.
Is anyone familiar enough with Ecto to know whether this is possible?