【问题标题】:Extracting Ecto fragment into variable将 Ecto 片段提取到变量中
【发布时间】:2020-04-06 02:52:13
【问题描述】:

我有一个片段,它是重复的并且相当复杂。我想将它提取到变量/函数中并多次重复使用,而不是多次编写它。这是一个简化的示例,到目前为止我尝试了许多不同的方法:

f = dynamic([u], fragment("order by name desc"))
query = from(u in User)
        |> order_by([u], ^f)
Repo.all(query)

根据documentation,使用dynamic 应该是可能的,但是我尝试在order_byselecthaving 或任何我收到类似于以下的错误消息:

(ArgumentError) expected a field as an atom, a list or keyword list in `order_by`, got: `dynamic([u], fragment("order by name desc"))`

我将如何实现它?


更新 1

这里有更真实的例子。以下代码有效:

    from(p in Photo,
      join: pv in assoc(p, :v),
      left_join: pl in assoc(p, :l),
      left_join: pc in assoc(p, :c),
      select: %{p | last_activity_at: fragment("greatest(?, ?, ?)", max(p.inserted_at), max(pl.inserted_at), max(pc.inserted_at))},
      group_by: p.id,
      order_by: [desc: fragment("greatest(?, ?, ?)", max(p.inserted_at), max(pl.inserted_at), max(pc.inserted_at))]
    )

但是,我无法通过提取片段或将其与动态或其他方式一起使用来使其工作。

【问题讨论】:

  • 你能试试|> order_by(f)吗?

标签: elixir ecto


【解决方案1】:

在与Ecto.Query.dynamic/2 相同的文档中有一个order_by 的示例

f = dynamic([u], fragment("order by name desc"))
# order_by = [desc: :name] # why not just this?
order_by = [desc: ^f]
query = from(u in User), order_by: ^order_by
Repo.all(query)

对于更新的示例:

order = dynamic(
  [p, pl, pc], 
  fragment(
    "greatest(?, ?, ?)",
    max(p.inserted_at),
    max(pl.inserted_at),
    max(pc.inserted_at)
  )
)

from(
  p in Photo,
  join: pv in assoc(p, :v),
  left_join: pl in assoc(p, :l),
  left_join: pc in assoc(p, :c),
  select: ...,
  group_by: p.id,
  order_by: ^[desc: order]
)

正如文档中所述,

不可能在根之外传递动态。例如,这不起作用:

 from query, order_by: [asc: ^dynamic(...)]

但这会:

from query, order_by: ^[asc: dynamic(...)]

【讨论】:

  • desc: :name 是一个简化的例子。请参阅我更新的一个更真实的例子的问题,我仍然无法工作。是的,我知道文档示例,这就是我尝试的方式以及您提出的建议,但同样的错误。 Ecto(或 Ecto.Sql)版本是否重要?
  • 我已根据您的更改更新了答案。
  • 我发现由于 ecto_sql (3.1.6) 较旧,我无法使用此语法。将它升级到 3.4.2 允许我使用这种语法。但是,我放弃了使用它,因为我还需要在 select: %{p | max_date: greatest...} 中使用它,但是无法使用。另外,我有一些having 声明。反正看起来不错,就是太难让它正常工作了。
猜你喜欢
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 2014-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多