Hello there,
I am running into some macro issues when using Ecto.Query. I want to define my actual select
function in a macro in order to reuse it later.
However, the code does not compile if the macro resides in a required module instead of the module actually doing the query:
defmodule A do
defmacro name_of(e) do
quote do
%{name_of: unquote(e).name}
end
end
end
defmodule AQuery do
require A
import Ecto.Query
# (Ecto.Query.CompileError) `A.name_of(e)` is not a valid query expression.
# If you want to invoke A.name_of/1 in a query, make sure that the module A
# is required and that name_of/1 is a macro
def query_test(), do: Repo.all(from e in Employee, select: A.name_of(e))
# Compiles & works
def fun_test(), do: A.name_of(%{name: "Hello World"})
end
defmodule BQuery do
import Ecto.Query
defmacro description_of(e) do
quote do
%{description_of: unquote(e).description}
end
end
# Compiles & works
def query_test(), do: Repo.all(from e in Employee, select: description_of(e))
# Compiles & works
def fun_test(), do: description_of(%{description: "Hello there"})
end
I also tried various combinations of trying to pin e
and/or the result of A.name_of/1
, without success.
What did I do wrong to make AQuery.query_test/0
work?
Thank you for your time!
$ elixir -v
Erlang/OTP 23 [erts-11.1.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Elixir 1.11.3 (compiled with Erlang/OTP 23)
$ cat mix.exs | grep ecto_sql -C 3
defp deps do
[
{:phoenix_pubsub, "~> 2.0"},
{:ecto_sql, "~> 3.4"},
{:postgrex, ">= 0.0.0"},
{:jason, "~> 1.0"},
]