Ecto查询中的条件参数

时间:2019-02-03 11:08:22

标签: elixir phoenix-framework ecto

我有一个参数platform,它是可选的:

def query_clicks(freq \\ "day", platform \\ false) do
    from(Click)
    |> select(
      [c],
      [
        fragment("date_trunc(?,?) as t", ^freq, c.inserted_at), count(c.link_id) ]
      )
      |> if platform, do: fn(q) -> where([c], c.platform == ^platform) end, else: fn(q): q end
    |> group_by([c], fragment("t"))
    |> Repo.all
  end

我试图破解某些内容(请参阅“如果平台...”),但是我不确定要使用的确切语法。我想做的是:

if platform != None:
  return query + WHERE statement
else:
  return query

什么是正确的语法?

2 个答案:

答案 0 :(得分:1)

您可以添加一个额外的功能maybe_platform/2

defp maybe_platform(queryable, nil), do: queryable
defp maybe_platform(queryable, platform) do
  queryable
  |> where([c], c.platform == ^platform)
end

然后您的query_clicks/2看起来像

def query_clicks(freq \\ "day", platform \\ false) do
  from(Click)
  |> select(
    [c],
    [
      fragment("date_trunc(?,?) as t", ^freq, c.inserted_at), count(c.link_id) 
    ]
  )
  |> maybe_platform(platform)
  |> group_by([c], fragment("t"))
  |> Repo.all
end

可以像您一样在匿名函数中完成此操作,但是imo更加清楚了。

答案 1 :(得分:0)

这可能为时已晚,但我只想分享我对这个问题的解决方案。 利用以下事实:通过Ecto macro api的任何方法(例如whereselectlimitoffset等)传递查询语句仍会返回可查询语句。 因此可以通过以下简单的方法完成:

def query_clicks(freq \\ "day", platform \\ false) do
  query = from(Click) |> select(...)

  (if platform, do: where(query, [c], c.platform == ^platform), else: query)
  |> group_by([c], fragment("t"))
  |> Repo.all
end

它的代码更少。希望能有所帮助:)