我正在尝试创建一个可以执行一些动态查询的函数。我想在一个条件下添加与另一个表的联接,但前提是opts
def list_fields(opts) do
query =
from f in Field,
select: %{
id: f.id,
type: f.type,
value: f.value
}
with query <- by_type(opts[:type], query),
query <- by_status(opts[:status], query) do
Repo.all(query)
end
end
我有以下功能可以过滤选择内容:
defp by_type(nil, query), do: query
defp by_type(type, query) do
from [f] in query, where: f.type == ^type
end
defp by_status(nil, query), do: query
defp by_status(status, query) do
from [f, d] in query, where: d.status == ^status
end
但是状态存储在另一个表上,除非不想避免结果重复,否则我不想向其添加联接。
带有联接的查询如下:
query =
from f in Field,
left_join: d in Data, on: d.field_id = f.id
select: %{
...
仅当left_join
中有:status
时,如何添加此opts
?
答案 0 :(得分:1)
使用Kernel.SpecialForms.with/1
的魔咒。
{_, query} =
with {status, query} when not is_nil(status) <-
{opts[:status], by_type(opts[:type], query)},
do: {:ok, by_status(opts[:status], query)}
Repo.all(query)
这里的窍门是,如果opts[:status]
为nil
,则第一个子句将返回而不会经过do
块,因此不会经过by_status
。