【问题标题】:How do interpolation fields in Ecto queries?Ecto 查询中的插值字段如何?
【发布时间】:2016-09-26 14:43:17
【问题描述】:

Ecto documentation 展示了如何进行插值。但我的查询中需要动态字段。我有几十个字段,为每个字段编写查询似乎没有凝聚力。

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

此控制器产生以下错误:

** (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

自动翻译。

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

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

    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
    

    field 期望字段是原子,所以我使用String.to_existing_atom 将字符串安全地转换为原子。由于您必须已经在模型的架构中定义了该字段,String.to_existing_atom 不会因任何有效的字段名称而失败。

    【讨论】:

    • 对于几十个动态字段我宁愿使用宏。
    • 抱歉,我开始编程,期待将我的想法放到网上。我还没有阅读宏会话。为什么会更好?所以效果很好。
    • @mudasobwa 你将如何在这里使用宏?你能扩大一点吗?我想不出任何理由在这里这样做,但也许我错过了一些东西。
    • @Dogbert 我已经发布了另一个 [过度简化] 答案来证明我的意思。
    【解决方案2】:

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

    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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-25
      • 2017-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多