From what I can tell:
- Key interpolation (key set at run time) works as long as the key is a string. Even query expressions work to some extent (e.g.
(a.id + 4)
doesn’t make much sense but it works). - atoms seem to only work as keys at compile time
defmodule Playground do
import Ecto.Query
alias MusicDB.Repo
alias MusicDB.Album
@keys [:run_time_key]
@keys_list Keyword.new(@keys, &{&1, Atom.to_string(&1)})
defp swap_key({to_key, from_key}, map) do
case Map.pop(map, from_key) do
{value, rest} ->
Map.put(rest, to_key, value)
_ ->
map
end
end
defp keys_swap(map),
do: List.foldl(@keys_list, map, &swap_key/2)
def play do
album_id = 4
query =
from(a in Album,
where: a.id == ^album_id,
select: %{}
)
key = "run_time_key"
fields = [:title]
query =
from(a in query,
select_merge: %{^key => map(a, ^fields)}
)
query
|> Repo.all()
# [%{"run_time_key" => %{title: "Portrait In Jazz"}}]
|> IO.inspect()
|> Enum.map(&keys_swap/1)
# [%{run_time_key: %{title: "Portrait In Jazz"}}]
|> IO.inspect()
:ok
end
end