如何提取 has_one 个关联的 id?

How to pluck id of has_one associations?

class Post
  has_one :latest_comment, -> { order(created_at: :desc) }, class_name: 'Comment'
end

我想做这样的事情:

Post.joins(:latest_comment).pluck('latest_comment.id')

但它不是有效的语法并且不起作用。

Post.joins(:latest_comment).pluck('comments.id')

以上有效,但 returns post 所有评论的 ID,不仅是最新的。

ActiveRecord::Assocations 是围绕 SQL 连接的一个非常漏洞的抽象,因此您的 has_one :latest_comment 关联实际上不会 return 连接中的单个行 table 每个记录,除非你在 Post.

的实例上调用它

相反,当你 运行 Post.joins(:latest_comment).pluck('comments.id') 你得到:

SELECT "comments"."id" 
FROM "posts" 
INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"

ActiveRecord 实际上不够聪明,无法知道您想从评论中获取唯一值 table - 它实际上只是表现得像一个 has_many 关联。在它的辩护中,这实际上不是以多语言方式做的事情。

您可以改为 select 注释中的行 table 并获取不同的值:

Comment.order(:post_id, created_at: :desc)
       .pluck(Arel.sql('DISTINCT ON (post_id) id'))

DISTINCT ON 是 Postgres 特定的。 RDBMS:es 之间的确切方法会有所不同,还有许多其他替代方法,例如横向连接、window 函数等,具体取决于您的性能要求。