I have a map :
allowed_lookup = %{coordinate: "15.0", id: 1}
I want to use this map to make a Ecto query to filter out some entries in database.
I am thinking something like this :
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)
So It will recursively apply all the filters present in map to get a queryset. But this code is not valid as q.x is not getting converted to q.coordinate or q.id .
Try this
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
accepts a keyword list where the field given as key is going to be compared with the given value. In this case using the simple [key: value]
construct for keyword list will not work since the field and value are dynamic. However, keyword list can also be constructed, dynamically, as list of tuple like [{key, value}]
.
iex> [{:a, 1}] == [a: 1] # true