如何构建动态的where子句?
How to build dynamic where clause?
我有字段名称列表,例如。 [:type, :car_id]
及其变更集
我想从每个字段中获取数据作为范围。
如何在从字段列表创建的每个表达式之间使用 and
构建动态 where 子句,我可以在之前创建的表达式中插入吗?
非动态示例:
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
您可以在初始查询中使用 Enum.reduce/3 来构建 wheres:
Enum.reduce([:type, :car_id], query, fn field, acc ->
value = get_field(changeset, field)
where(acc, [m],field(m, ^field) == ^value)
end)
由于您想在 ==
上进行比较并将它们与 and
相结合,您可以简单地将关键字列表传递给 where
,利用 Ecto 2.0 中的 Bindingless Queries +:
def scoped_query(query, changeset, fields_names) do
criteria = for field <- fields_names, do: {field, get_field(changeset, field)}
query |> where(^criteria)
end
我有字段名称列表,例如。 [:type, :car_id]
及其变更集
我想从每个字段中获取数据作为范围。
如何在从字段列表创建的每个表达式之间使用 and
构建动态 where 子句,我可以在之前创建的表达式中插入吗?
非动态示例:
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
您可以在初始查询中使用 Enum.reduce/3 来构建 wheres:
Enum.reduce([:type, :car_id], query, fn field, acc ->
value = get_field(changeset, field)
where(acc, [m],field(m, ^field) == ^value)
end)
由于您想在 ==
上进行比较并将它们与 and
相结合,您可以简单地将关键字列表传递给 where
,利用 Ecto 2.0 中的 Bindingless Queries +:
def scoped_query(query, changeset, fields_names) do
criteria = for field <- fields_names, do: {field, get_field(changeset, field)}
query |> where(^criteria)
end