我必须过滤一个在某些情况下可以接受逗号分隔值的索引。我在Ecto工作,没有凤凰(和牛仔一起)。
我的索引将支持这样的搜索
/users?ids=1,2,3&email=simple@email.com&another=something
其中电子邮件字段不允许使用多个参数,并且ID支持多个ID
这是我尝试过的
def list_all(query_params) do
filtered_params = prepare_list_query(query_params)
User
|> where(^filtered_params)
|> Repo.all()
end
# In order to simplify queries I decided to manage all queries as IN clause
# it will returns [id: [1,2,3], email:["something@mymail.com"]]
defp prepare_list_query(query_params) do
query_params
|> Map.take(~w(ids email another))
# Careful: read reference #1 above
|> Enum.map(fn {name, value} ->
case name do
"ids" -> {:id, String.split(value, ",")}
single_param -> {String.to_atom(single_param), [value]}
end
end)
end
这很棘手,但我的想法是回来
[id: [1,2,3], email:["something@mymail.com"]]
,然后将所有过滤器用作IN子句。
此过滤器必须支持发送零个,一个或所有参数。
我是长生不老药世界中的新人,我正在迈出第一步。
预先感谢:)。
答案 0 :(得分:2)
您可以使用Enum.reduce/3
根据参数动态构建ecto查询
def list_all(query_params) do
query = User # initial query
query_params
|> Map.take(~w(ids email another))
|> Enum.reduce(query, fn
{_key, value} when value in [nil, ""], q ->
q # ignore empty values
{"ids", value}, q ->
ids = String.split(values, ",")
q |> where([r], r.id in ^ids)
{key, value} ->
args = [{key, value}]
q |> where(^args)
end
end)
|> Repo.all()
end
在reduce函数中,您可以添加新子句来处理不同的键和值。