Sie können dafür "bindingless queries" verwenden, aber es gibt ein Problem. Ecto erwartet die Spaltennamen als Atome und das Argument als Keyword-Liste. Letzteres ist einfach, aber converting arbitrary user input into atoms may result in the Erlang VM crashing. Hier ist ein sicherer Weg, dies mit einer weißen Liste von Spaltennamen zu tun:
# user input
params = %{"first_name" => "John", "last_name" => "Smith", "age" => 28}
filtered_params =
params
|> Map.take(~w(first_name last_name age))
|> Enum.map(fn {k, v} -> {String.to_atom(k), v} end)
from(MyApp.Person, where: ^filtered_params)
|> MyApp.Repo.all
|> IO.inspect
Ausgang:
[debug] SELECT p0."id", p0."first_name", p0."last_name", p0."age", p0."inserted_at", p0."updated_at" FROM "people" AS p0 WHERE (((p0."age" = ?) AND (p0."first_name" = ?)) AND (p0."last_name" = ?)) [28, "John", "Smith"] OK query=6.5ms queue=14.8ms
[%MyApp.Person{__meta__: #Ecto.Schema.Metadata<:loaded>, age: 28,
first_name: "John", id: 1, inserted_at: #Ecto.DateTime<2016-06-11T16:01:49Z>,
last_name: "Smith", updated_at: #Ecto.DateTime<2016-06-11T16:01:49Z>}]
Beachten Sie, dass 'Repo.get_by' nur 0 oder 1 Ergebnis verwendet wird, holen (s). Wenn die Abfrage mehr als 1 Ergebnisse zurückgibt, wird ein Fehler ausgelöst. – Dogbert