我有一个 IndexQuery,我可以在其中丰富一组用户,然后对其应用不同的过滤器。
class Users::IndexQuery
def initialize(users)
@users = users
end
def call
@users.kept.created_desc
.select(
"users.*",
"COALESCE(paid_invoices.paid_amount_cents,0) AS paid_amount_cents",
"COALESCE(unpaid_invoices.unpaid_amount_cents,0) AS unpaid_amount_cents",
)
.joins(joins_paid_invoices, joins_unpaid_invoices, :subscription)
.includes(:subscription)
end
private
def joins_paid_invoices
@joins_paid_invoices ||= <<-SQL
LEFT OUTER JOIN (
SELECT invoices.user_id as user_id,
SUM(invoices.amount_cents) as paid_amount_cents
FROM invoices
WHERE invoices.status = 'paid'
GROUP BY user_id
)
AS paid_invoices
ON paid_invoices.user_id = users.id
SQL
end
def joins_unpaid_invoices
@joins_unpaid_invoices ||= <<-SQL
LEFT OUTER JOIN (
SELECT invoices.user_id AS user_id,
SUM(invoices.amount_cents) as unpaid_amount_cents
FROM invoices
WHERE invoices.status = 'unpaid'
GROUP BY user_id
)
AS unpaid_invoices
ON unpaid_invoices.user_id = users.id
SQL
end
end
这是控制器中发生的事情:
enriched_users = ::Users::IndexQuery.new(User.all.includes(:account)).call
if params.dig(:q, :extra_params, :preset_filter).present?
enriched_users = enriched_users.where("subscriptions.status = ?", "in_trial").order("subscriptions.trial_end ASC")
end
但是,在控制台中以 .to_sql
结尾运行查询会打印以下内容:
ORDER BY \"users\".\"id\" DESC, subscriptions.trial_end ASC"
控制器和 IndexQuery
中都没有我指定它应该按 Users.id
排序。可能有什么问题,为什么默认情况下按该属性排序?
编辑:我在 IndexQuery 中有一个 GROUP BY users.id
。这可能是问题吗?
答案 0 :(得分:1)
在 Postgres 9.4+ 上,您可以大大简化by using FILTER
,这让您可以对聚合函数的结果设置条件:
{{1}}
但老实说,我不明白你为什么要将它提取到它自己的对象中,而不是仅仅在模型中创建一个范围/类方法,因为这是一个非常复杂的解决方案。