I’m trying to dynamically build up a query. Imagine I have two ecto schemas, e.g.
defmodule Make do
use Ecto.Schema
schema "makes" do
field :name, :string
....
end
end
defmodule Model do
use Ecto.Schema
schema "models" do
field :name, :string
...
belongs_to :make, Make
end
...
end
I want to end up with a query like:
from m in Model, join: a in assoc(m, :make), select: %{model_name: m.name, make_name: m.name}
, but I am generating the query from some metadata rather than explicitly, e.g. [model: [:name, make: name]].
I can generate the query with joins and select/select_merge as needed to return just the fields I am interested in, but I cannot figure out how to combine select_merge, map, and selected_as to allow me to avoid name collisions in my select. I’ve bumped into my limits on macros, and I could use some help, please.
I’m basically stuck on a call as follows, that works but does not deal with naming collisions:
select_merge(query, [{^assoc, x}], map(x, ^[field]))
I can see from the ast of the query that I want to end up with a chunk like:
select: {:%{}, [],
[
model_name: {{:., [], [{:m, [], Elixir}, :name]}, [no_parens: true], []},
make_name: {{:., [], [{:a, [], Elixir}, :name]}, [no_parens: true], []}
]}
Where my select expr becomes:
%Ecto.Query.SelectExpr{
expr: {:%{}, [],
[
model_name: {{:., [], [{:&, [], [0]}, :name]}, [], []},
make_name: {{:., [], [{:&, [], [1]}, :name]}, [], []}
]},
file: "iex",
line: 1,
fields: nil,
params: [],
take: %{},
subqueries: [],
aliases: %{}
}
Thanks in advance for any help!