如何从 Arel 中的别名 table 生成 select?

How can I generate a select from an aliased table in Arel?

我需要使用 Arel 以

的形式生成 SQL
SELECT c2.user_id, MAX(c2.created_at) as max_created_at
FROM comments AS c2
GROUP BY c2.user_id

在更大的查询中用作子查询

SELECT *
FROM comments
INNER JOIN (...subquery...) s1
ON comments.user_id = s1.user_id
AND comments.created_at = s1.max_created_at

我不知道如何在子查询中为 comments table 添加别名。

我能得到的最接近的是

c2 = Comment.arel_table.alias
s1 = Comment.arel_table.project(
    c2[:user_id], c2[:created_at].maximum.as('max_created_at')
    ).group('user_id').as('s1')

但这会生成不正确的 SQL

SELECT c2.user_id, MAX(c2.created_at) as max_created_at
FROM comments
GROUP BY c2.user_id

(错误,因为未定义 c2)

生成没有别名的查询会导致不正确的结果,因为子查询内外的 table 名称会发生​​冲突。

这给出了 Arel::TableAliasproject 方法的错误。

s1 = c2.project(...

如何使用 Arel 查询别名 table?

您可以使用 from 来告诉它从哪个 table(或者在本例中,table 别名)进行投影:

c2 = Comment.arel_table.alias
s1 = Comment.arel_table.
  project(c2[:user_id], c2[:created_at].maximum.as('max_created_at')).
  from(c2).group('user_id').as('s1')
puts s1.to_sql
# (SELECT "comments_2"."user_id", MAX("comments_2"."created_at") AS max_created_at
#  FROM "comments" "comments_2" GROUP BY user_id) s1