仅当参数存在时,如何在ecto中定义联接?

时间:2019-09-19 21:56:17

标签: elixir ecto

我正在尝试创建一个可以执行一些动态查询的函数。我想在一个条件下添加与另一个表的联接,但前提是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

1 个答案:

答案 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