I'm learning Elixir and came across such situation:
I have an Ecto schema and I want to make a function like "get_by" that takes a column name and it's value as an arguments like this: get_by(:id, 7)
So the working version of the function would be like this:
def get_by(column, value) do
Repo.all(
from(
r in __MODULE__,
where: field(r, ^column) == ^value,
)
)
end
I know this is fully functional but I was wondering how the field
macro works.
The original code is too hard to read for me. I was trying to play with AST in macro, but nothing seems to work. The best I had was this:
defmacro magic(var, {:^, _, [{column, _, _}]}) do
dot = {:., [], [var, column]}
{dot, [], []}
end
But this returns r.column
instead of the atom bound to column
variable.
How the macro should be written to return r.id
?
Ecto.Query.API.field/2
, it's just a placeholder: github.com/elixir-ecto/ecto/blob/v3.2.5/lib/ecto/query/… The query macro looks for calls to it and treats them as desired. – Brett Beatty