Hi every one!
I’m a bit lost trying to compose a queries using macro.
defmacrop to_query(params, append_to_query) do
quote do
unquote(params)
|> case do
{:order, value} ->
from q in unquote(append_to_query), order_by: [{^value, :id}]
{key, value} when is_bitstring(value) ->
from q in unquote(append_to_query), where: like(q ? key, ^"%#{value}%")
{key, value} ->
from q in unquote(append_to_query), where: q ? key == ^value
_ ->
unquote(append_to_query)
end
end
end
@spec compose(Ecto.Schema.t(), Keyword.t) :: Ecto.Query.t()
def compose(schema, params) do
with true <- Code.ensure_compiled?(schema) do
Enum.reduce(params, (from q in schema),
fn attrs, acc -> to_query(attrs, acc) end)
else
_ -> raise ArgumentError, message: "Invalid schema #{schema}"
end
end
As you can see in that line with <q ? key>, I need to call unquoted key value from q in order to compare. As I can’t do: q.unquote(key) or q.(unquote(key)) because its not a function. Also was thinking to get to code from string like : "q.#{unquote(key) " and then expand to code, but didn’t found any examples.
Some one know how it can be done?
I checked Macro documentation it is still black magic to me but I want to learn it even more!
Thank you!