在由OR连接的where子句中组成具有多个列的Ecto查询

Jos*_*ken 9 elixir ecto

假设我有这个问题:

User
|> where([u], u.name == "John" or u.age == 24)
Run Code Online (Sandbox Code Playgroud)

我想把它变成一个函数,可以获取字段名称和字段值的关键字列表,并动态生成相同的查询.函数定义看起来像这样:

def where_any(query, field_names_to_values) do
  ...
end
Run Code Online (Sandbox Code Playgroud)

Elixir和Ecto有可能吗?

jis*_*one 2

通常不会提倡使用宏,但 ecto 具有如此复杂的魔力,我认为在这种情况下最好保持抽象语法树完整。

defmacro any_expr(var, [{key, value} | rest]) do
  Enum.reduce(
    rest,
    quote do unquote(var).unquote(key) == unquote(value) end,
    fn ({k, v}, acc) ->
      quote do: unquote(acc) or unquote(var).unquote(k) == unquote(v)
    end)
end
Run Code Online (Sandbox Code Playgroud)

应该像这样工作:

User
|> where([u], any_expr(u, [name: "John", age: 24]))
Run Code Online (Sandbox Code Playgroud)

(请注意,这是未经测试的代码......)