Josh Rieken
Josh Rieken

Reputation: 2266

Composing an Ecto query with multiple columns in a where clause joined by OR

Let's say I have this query:

User
|> where([u], u.name == "John" or u.age == 24)

I want to turn this into a function that can take a keyword list of field names and field values and dynamically generate this same query. The function definition would look something like this:

def where_any(query, field_names_to_values) do
  ...
end

Is this possible with Elixir and Ecto?

Upvotes: 9

Views: 2263

Answers (1)

jisaacstone
jisaacstone

Reputation: 4264

Wouldn't normally advocate a macro, but ecto does so much complex magic I think it's best in this case to keep the abstract syntax tree intact.

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

should work like this:

User
|> where([u], any_expr(u, [name: "John", age: 24]))

(note that this is untested code...)

Upvotes: 2

Related Questions