Reputation: 2400
I have list of field names eg. [:type, :car_id]
and changeset whereof
I want to get data from each field as scope.
How to build dynamic where clause with and
between each expression created from list of fields, can I interpolate in where expression created earlier?
Not dynamic example:
def scoped_query(query, changeset, fields_names) do
type_field = List.first(fields_names)
car_id_field = List.last(fields_names)
scope1 = get_field(changeset, type_field)
scope2 = get_field(changeset, car_id_field)
query |> where([m], field(m, ^type_field) == ^scope1 and field(m, ^car_id_field) == ^scope2)
end
Upvotes: 1
Views: 1101
Reputation: 222138
Since you want to compare on ==
and join them with and
, you can simply pass a keyword list to where
making use of Bindingless Queries in Ecto 2.0+:
def scoped_query(query, changeset, fields_names) do
criteria = for field <- fields_names, do: {field, get_field(changeset, field)}
query |> where(^criteria)
end
Upvotes: 5
Reputation: 84150
You can use Enum.reduce/3 with the initial query to build up the wheres:
Enum.reduce([:type, :car_id], query, fn field, acc ->
value = get_field(changeset, field)
where(acc, [m],field(m, ^field) == ^value)
end)
Upvotes: 1