Hi,
I want to write a simple macro to generate a dynamic fragment.
defmodule MyApp.Spike do
import Ecto.Query, warn: false
defmacro filter_address_fragment(field_name, value) do
field_name_str = to_string(field_name)
sql = "#{field_name_str}->>'name' ilike ?"
quote do
fragment(unquote(sql), unquote(value))
end
end
def filter_address(query, field_name, value) do
where(query, [p], filter_address_fragment(field_name, value))
end
end
When I try to compile the app I get the following error.
== Compilation error in file lib/spike.ex ==
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:field_name, [line: 14], nil} of type Tuple
(elixir 1.14.4) lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir 1.14.4) lib/string/chars.ex:22: String.Chars.to_string/1
(stdlib 4.3.1) erl_eval.erl:748: :erl_eval.do_apply/7
(stdlib 4.3.1) erl_eval.erl:492: :erl_eval.expr/6
(stdlib 4.3.1) erl_eval.erl:136: :erl_eval.exprs/6
expanding macro: MyApp.Spike.filter_address_fragment/2
lib/spike.ex:14: MyApp.Spike.filter_address/3
(ecto 3.11.2) expanding macro: Ecto.Query.where/3
However, when I removed filter_address
function the code compiles just fine. What did I do wrong?