Elixir phoenixframework中的外部动态查询参数

Elixir phoenixframework中的外部动态查询参数,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我不熟悉长生不老药和凤凰框架。如何将参数动态添加到EXTO查询?例如: def index(conn, _params) do departments = Repo.all(Department) render(conn, "index.json", data: departments) end 是否可以在EXTO查询中使用_参数?比如: Repo.get_by(Department, _params) 当然,您可以动态地获取内容,在第二个参数中,需要Keyword.t | Map.

我不熟悉长生不老药和凤凰框架。如何将参数动态添加到EXTO查询?例如:

def index(conn, _params) do
  departments = Repo.all(Department)
  render(conn, "index.json", data: departments)
end
是否可以在EXTO查询中使用_参数?比如:

Repo.get_by(Department, _params)

当然,您可以动态地获取内容,在第二个参数中,需要Keyword.t | Map.t,可以是关键字,也可以是映射。您可以直接从参数将其设置为映射或关键字,并将其传递到查询中。 范例


正如@Dogbert在评论中所说的那样,get_by将得到0或1个结果,更多的结果将产生错误。我之所以用它,是因为你在这个问题上总是得过且过

当然,您可以动态地获取内容,在第二个参数中,Keyword.t | Map.t是一个关键字或一个映射。您可以直接从参数将其设置为映射或关键字,并将其传递到查询中。 范例

正如@Dogbert在评论中所说的那样,get_by将得到0或1个结果,更多的结果将产生错误。我之所以用它,是因为你在这个问题上总是得过且过

您可以使用它,但有一个问题。Ecto希望列名是原子,参数是关键字列表。后者很容易,但是。以下是使用列名白名单进行此操作的安全方法:

# 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
输出:

[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>}]
你可以用这个,但有个问题。Ecto希望列名是原子,参数是关键字列表。后者很容易,但是。以下是使用列名白名单进行此操作的安全方法:

# 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
输出:

[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>}]
请注意,Repo.get_by仅用于获取0或1个结果。如果查询返回多个结果,则会引发错误。请注意,Repo.get_by仅用于获取0或1个结果。如果查询返回多个结果,则会引发错误。