I’m looking to define a couple of macros in different modules to use them in my ecto queries, as part of the
where conditions inside a
Ecto.Query.from call. The problem I’m facing is how to call the macros by their fully qualified name (i.e.
MyModule.my_macro), without importing the module and using the short name.
A simplified example of what I tried:
defmodule Order do schema "orders" do … end defmacro recent(o) do quote do unquote(o).inserted_at > ago(5, "day") end end end defmodule Quote do schema "quotes do … end defmacro recent(q) do quote do unquote(q).inserted_at > ago(3, "day") end end end
# my_context.ex > require Quote > Repo.all(from(q in Quote, where: Quote.recent(q)) # ** (Ecto.Query.CompileError) `Quote.recent(q)` is not a valid query expression. If you want to invoke Quote.recent/1 in a query, make sure that the module Quote is required and that recent/1 is a macro > require Order > Repo.all(from(o in Order, where: Order.recent(o))
I’m afraid this is a limitation of the way
Macro.postwalk to parse the query expressions. But I would like someone to confirm (or refute) my suspicion. And could Ecto theoretically be extended to support this case, or is it a hard limitation?