Search code examples
elixirecto

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


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 .


Solution

  • 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