【发布时间】:2016-04-03 19:50:47
【问题描述】:
我正在使用 ActiveRecord 4.2 / Arel 6.0 / Postgres 并有以下输入:
-
Arel::Attributes::Attribute来自Arel::Table(column) - 多个
Arel::Nodes::Ordering节点 (orders)
我想使用聚合函数构建一个 Arel::Nodes::NamedFunction,该函数包含由 Attribute 指定的列并按 Ordering 节点排序。
生成的 SQL 可能类似于:
array_agg("posts"."id" ORDER BY "posts"."published_at" DESC)
我目前的解决方案是首先构建一个Arel::Nodes::SelectStatement,向其中添加列和订单,将其转换为 SQL,去除前导 SELECT 关键字,将其包装在 Arel::Nodes::SqlLiteral 中并将其传递给 @987654333 @节点:
select = Arel::Nodes::SelectStatement.new
select.cores.last.projections << column
select.orders = orders
sql = select.to_sql.sub(/^SELECT /, '')
literal = Arel::Nodes::SqlLiteral.new(sql)
array_agg = Arel::Nodes::NamedFunction.new('array_agg', [literal])
显然,这是一个巨大的黑客攻击。
将ORDER BY 保留在聚合函数之外不是一种选择,因为它会与用于聚合的GROUP BY 冲突。
那么有没有一种更简洁的方法可以在不滥用 SelectStatement / SelectManager 的情况下实现这一目标?
【问题讨论】:
标签: ruby-on-rails rails-activerecord arel