Elixir 如何在EXTO查询中使用插值字段?

Elixir 如何在EXTO查询中使用插值字段?,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,显示了如何执行插值值。但我的查询中需要动态字段。我有几十个字段,为每个字段编写的查询似乎都不连贯 defmodule Hedone.SearchController do use Hedone.Web, :controller alias Hedone.User def idade(conn, %{"idade+" => maior, "idade-" => menor, "campo" => campo}) do IO.inspect campo

显示了如何执行插值值。但我的查询中需要动态字段。我有几十个字段,为每个字段编写的查询似乎都不连贯

defmodule Hedone.SearchController do
  use Hedone.Web, :controller

  alias Hedone.User

  def idade(conn, %{"idade+" => maior, "idade-" => menor, "campo" => campo}) do
    IO.inspect campo
  query = from u in User, where: u.campo > ^maior and u.campo < ^menor, select: u.name
  pesquisa = Repo.all query
  IO.inspect pesquisa
  text conn, "Works"
end

end
defmodule Hedone.SearchController do
使用Hedone.Web,:controller
别名Hedone.User
定义idade(conn,%%{“idade+”=>maior,“idade-”=>menor,“campo”=>campo})do
伊奥·坎波
query=来自用户中的u,其中:u.campo>^maior和u.campo<^menor,选择:u.name
pesquisa=Repo.all查询
伊奥·佩斯基萨
文本控制,“工作”
结束
结束
此控制器生成以下错误:

** (Ecto.QueryError) web/controllers/search.ex:8: field `Hedone.User.campo` in `where` does not exist in the schema in query:

from u in Hedone.User,
  where: u.campo > ^18 and u.campo < ^40,
  select: u.name
**(exto.QueryError)web/controllers/search.ex:8:field`Hedone.User.campo`in`where`在查询的架构中不存在:
来自Hedone.User中的u,
其中:u.campo>^18和u.campo<^40,
选择:u.name

自动翻译。

我假设
campo
包含一个字符串,其中包含要使用的字段名称,例如
“age”
。您可以在此查询中使用:

def idade(conn, %{"idade+" => maior, "idade-" => menor, "campo" => campo}) do
  campo = String.to_existing_atom(campo)
  query = from u in User, where: field(u, ^campo) > ^maior and field(u, ^campo) < ^menor, select: u.name
  pesquisa = Repo.all query
  IO.inspect pesquisa
  text conn, "Works"
end
def-idade(conn,%%{“idade+”=>maior,“idade-”=>menor,“campo”=>campo})做什么
campo=字符串。到现有的原子(campo)
query=来自用户中的u,其中:字段(u,^campo)>^maior和字段(u,^campo)<^menor,选择:u.name
pesquisa=Repo.all查询
伊奥·佩斯基萨
文本控制,“工作”
结束

field
希望字段是一个原子,因此我使用了
String.to\u现有的\u atom
将字符串安全地转换为原子。由于您必须已经在模型的架构中定义了字段,
String.to\u existing\u atom
对于任何有效的字段名都不会失败。

我假设
campo
包含一个字符串,其中包含您要使用的字段名,例如
“age”
。您可以在此查询中使用:

def idade(conn, %{"idade+" => maior, "idade-" => menor, "campo" => campo}) do
  campo = String.to_existing_atom(campo)
  query = from u in User, where: field(u, ^campo) > ^maior and field(u, ^campo) < ^menor, select: u.name
  pesquisa = Repo.all query
  IO.inspect pesquisa
  text conn, "Works"
end
def-idade(conn,%%{“idade+”=>maior,“idade-”=>menor,“campo”=>campo})做什么
campo=字符串。到现有的原子(campo)
query=来自用户中的u,其中:字段(u,^campo)>^maior和字段(u,^campo)<^menor,选择:u.name
pesquisa=Repo.all查询
伊奥·佩斯基萨
文本控制,“工作”
结束

field
希望字段是一个原子,因此我使用了
String.to\u现有的\u atom
将字符串安全地转换为原子。由于您必须已经在模型的架构中定义了字段,
String.to\u existing\u atom
对于任何有效的字段名都不会失败。

我将此作为解决问题的另一种方法的示例发布。可以使用宏来处理此转换,因为宏是在编译时解析的:

defmacro idade(conn, formula, campo: binding) do
  q = formula |> String.replace "campo", binding
  quote do
    from u in User, where: unquote(q), select: u.name
      |> Repo.all
    text conn, "Works"
  end
end
把它叫做:

idade(nil, "u.campo > ^maior and u.campo < ^menor", campo: "age")
idade(无,“u.campo>^maior”和u.campo<^menor”,campo:“年龄”)

我将此作为解决问题的另一种方法的示例发布。可以使用宏来处理此转换,因为宏是在编译时解析的:

defmacro idade(conn, formula, campo: binding) do
  q = formula |> String.replace "campo", binding
  quote do
    from u in User, where: unquote(q), select: u.name
      |> Repo.all
    text conn, "Works"
  end
end
把它叫做:

idade(nil, "u.campo > ^maior and u.campo < ^menor", campo: "age")
idade(无,“u.campo>^maior”和u.campo<^menor”,campo:“年龄”)

对于几十个动态字段,我宁愿使用宏。对不起,我正在开始编程,并期待着将我的想法放到网上。我还没有读过宏会话。为什么会更好?所以它工作得很好。@mudasobwa您在这里如何使用宏?你能把范围扩大一点吗?我想不出任何理由在这里这么做,但也许我遗漏了什么。@Dogbert我已经发布了另一个[过于简单化]的答案来证明我的意思。对于几十个动态字段,我宁愿使用宏。对不起,我正在开始编程,并期待着将我的想法放到网上。我还没有读过宏会话。为什么会更好?所以它工作得很好。@mudasobwa您在这里如何使用宏?你能把范围扩大一点吗?“我想不出任何理由在这里这么做,但也许我遗漏了什么。”多伯特我已经发布了另一个[过于简单化的]答案来证明我的意思。