I’m writing an ecto query builder which can generate queries dynamically from phoenix params maps, like rummage. This requires using the Ecto.Query.dynamic/2
macro, which is actually quite simple and intuitive, but I’m having the following problem:
I’d like the users of my library to be able to write this:
import Ecto.Query, only: [from: 2]
from x in MySchema,
where: build_query_from_params(MySchema, params),
where: custom_condition,
join: custom_join # etc.
To build the query dynamically, I need something like:
def add_filter_to_query(fragment, "greater_than_or_equal_to", field_atom, value) do
dynamic([x], field(x, ^field_atom) >= ^value and ^fragment)
end
The problem is that this forces the user to use x
as the variable name for the query. I could bypass this by writing the from x in MySchema
myself, but then it would be hard for the user to add custom filters because I’d be fixing the variable name, which should be an implementation detail…
Is there any way I can pass a variable name into the dynamic/2
macro so that this stops being a problem?
For example, something like this:
def add_filter_to_query(fragment, "greater_than_or_equal_to", field_atom, value, variable) do
dynamic([variable], field(variable, ^field_atom) >= ^value and ^fragment)
end
The above code doesn’t work, of course, but I think it explains what I’m after.