如何构建动态where子句?

时间:2016-09-08 14:15:42

标签: elixir phoenix-framework ecto

我有字段名称列表,例如。 [: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

2 个答案:

答案 0 :(得分:5)

由于您希望在==上进行比较并将其加入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

答案 1 :(得分:1)

您可以使用Enum.reduce/3与初始查询建立起来:

Enum.reduce([:type, :car_id], query, fn field, acc ->
  value = get_field(changeset, field)
  where(acc, [m],field(m, ^field) == ^value)
end)