如何在 Ecto 查询中的 where 子句中使用变量

How to use variables in in a Ecto query in where clause

我有一张地图:

  allowed_lookup = %{coordinate: "15.0", id: 1}

我想用这张地图做一个 Ecto 查询来过滤掉数据库中的一些条目。

我在想这样的事情:

Enum.reduce(allowed_lookup, Project.Models.Grid,
            fn {x,y}, query ->
                IO.puts "#{inspect x} , #{inspect y}"
                query = where(query, [q] , q.x == ^y)
            end)

queryset = Project.Repo.all(query)

所以它将递归地应用地图中存在的所有过滤器来获取查询集。 但是此代码无效,因为 q.x 未转换为 q.coordinate 或 q.id 。

试试这个

allowed_lookup = %{coordinate: "15.0", id: 1}
Enum.reduce(allowed_lookup, Project.Models.Grid,
        fn {x,y}, query ->
            IO.puts "#{inspect x} , #{inspect y}"

            field_query = [{x, y}] #dynamic keyword list

            query|>where(^field_query)
        end)

queryset = Project.Repo.all(query)

Ecto.Query.where 接受关键字列表,其中作为键给出的字段将与给定值进行比较。在这种情况下,对关键字列表使用简单的 [key: value] 结构将不起作用,因为字段和值是动态的。但是,关键字列表也可以动态构造为元组列表,如 [{key, value}]

 iex> [{:a, 1}] == [a: 1] # true