Elixir ECTO学習時に、キーワードクエリを使って、Ectoクエリを補間(Interpolation)した場合、補間前に設定していた別名が使えなくて、悩んだので、その対策について記載します。
テーブル構造はこんな形です。サンプルデータを正規化して用意しました。
(やりたかったこと)
以下のようにEctoクエリを補間したのに変数がバインドされていないとエラーがでます。
他のサイトの例など調べていると、実行できているように見えたのですが、ダメでした。
iex> import Ecto.Query
iex> alias Olympic.Repo
iex> goldmedal = from r in Olympic.Result, where: [medal: "Gold"] #Ecto.Query<from r0 in Olympic.Result, where: r0.medal == "Gold">
iex> Repo.all(from a in Olympic.Athlete, join: ^goldmedal, on: [athleteid: a.athleteid], where: a.sex == "M", select: {a.name, r.team, r.games, r.sport, r.event, r.medal})
** (Ecto.Query.CompileError) unbound variable `r` in query. If you are attempting to interpolate a value, use ^var
(ecto 3.9.2) expanding macro: Ecto.Query.select/3
iex:20: (file)
(ecto 3.9.2) expanding macro: Ecto.Query.from/2
iex:20: (file)
(対策)
補間後に別名を設定すれば別名が設定でき、取得したいデータが取得できました。
iex> goldmedal = from Olympic.Result, where: [medal: "Gold"] #Ecto.Query<from r0 in Olympic.Result, where: r0.medal == "Gold"
iex> Repo.all(from a in Olympic.Athlete, join: r in ^goldmedal, on: [athleteid: a.athleteid], where: a.sex == "M", select: {a.name, r.team, r.games, r.sport, r.event, r.medal})
00:24:57.324 [debug] QUERY OK source="athletes" db=242.1ms queue=23.0ms idle=1053.9ms
SELECT a0."name", r1."team", r1."games", r1."sport", r1."event", r1."medal" FROM "athletes" AS a0 INNER JOIN "results" AS r1 ON (r1."medal" = 'Gold') AND (r1."athleteid" = a0."athleteid") WHERE (a0."sex" = 'M') []
[
{"Edgar Lindenau Aabye", "Denmark/Sweden", "1900 Summer", "Tug-Of-War",
"Tug-Of-War Men's Tug-Of-War", "Gold"},
・・・省略
同じように悩んだ人がいればご参考に。
(環境)
Windows 11
psql (PostgreSQL) 15.0
postgrex 0.16.5
ecto_sql 3.9
iex 1.14.0