Referencing Ecto schemas from the PaginationPlanner #5
Replies: 1 comment
-
|
Hi @bencoppock, sorry for the delay. Work has been a bit chaotic this week...
I had little time to look at the code base, but I figure we could just wrap the current code to allow a module to be passed, WDYT? Do you think it would be a problem to always cast the values? I think we could assume this would be standard for Ecto - except for cases where you want to use schemaless queries, of course. defmacro paginate_by(query_name, module, do: {:__block__, _, sorts}) do
sorts = Enum.map(sorts, fn {:sort, _, args} -> parse_sorts(args, module) end)
implement(query_name, sorts)
end
@doc false
def parse_sorts([dir, field], module \\ nil)
def parse_sorts([dir, field], nil), do: {dir, field, nil}
def parse_sorts([dir, field], module), do: {dir, field, module.__schema__(:type, field)}
def parse_sorts([dir, field, [type: type]], nil), do: {dir, field, type}
What if we just keep using the named bindings but instead add it using the module name as a convention? I mean, do you think we could just translate this call |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Picking up the conversation from this issue…
@thiagomajesk, you brought up the idea of referencing Ecto schemas in the pagination planner and then automatically figuring out types and aliases from that:
This seems like an interesting potential improvement, but I'm not quite sure how it would work…
I think figuring out the types would be trivial. For example, I believe we can call
Merchant.__schema__(:type, : id)to find out that field is a UUID. But would we have to then cast all fields to whatever type their schema dictates? (Currently, I only cast if you've explicitly set a customtype:in yoursortclause.)But as for figuring out bindings, I'm not sure how that would work. Do you know of a clean way to accept a query (in the
Chunkr.Pagination.paginate/4function) and then extend that query with aselect,where, etc. while binding to the proper fields? I'm using Ecto's named bindings so that we can refer to bindings that haven't even been established yet at compilation time. Which has the nice extra benefit that you can bind to fields that don't actually exist (e.g. dynamically generated values).As a side note, a big motivation I had for using this macro pattern for setting up pagination strategies at compile time is because it's the only way I could figure out to support Ecto fragments within pagination strategies…and I very much wanted to support fragments (in my experience, it's common to want to do things like downcase strings before sorting in order to achieve case-insensitive sorts, etc.). Also, using macros this way allows Chunkr to basically pass any valid field or fragment through to an Ecto query while remaining ignorant of how any of it actually works (so long as they use named bindings)—which is super nice and flexible for Chunkr! 😄
Beta Was this translation helpful? Give feedback.
All reactions