2016-01-26 7 views
9

Diciamo che ho questo query:Comporre una query Ecto con più colonne in una clausola WHERE hanno aderito da O

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

voglio trasformare questo in una funzione che può prendere un elenco di parole chiave dei nomi di campo e campo valori e generare dinamicamente questa stessa query. La definizione della funzione sarebbe simile a questa:

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

E 'possibile con Elixir ed Ecto?

+1

faccio questo tipo di componibilità in una libreria di mine con le macro come suggerisce @jisaacstone . Vedere https://github.com/rcdilorenzo/filtrex/blob/master/test/ast_test.exs per un esempio. –

risposta

2

Normalmente non difenderebbe una macro, ma ecto fa una magia così complessa penso che sia meglio in questo caso mantenere intatto l'albero della sintassi astratta.

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 

dovrebbe funzionare in questo modo:

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

(notare che questo è il codice non testato ...)