Rails 5 - 对急切加载的子集合应用限制

Rails 5 - Apply limit to eagerly loaded children of collection

我需要帮助生成对集合的子项应用限制的查询。这是我的问题的简单演示。

Post 型号

class Post < ApplicationRecord
  has_many :comments
end

评论模型

class Comment < ApplicationRecord
  belongs_to :post
end

我想在视图中显示所有 post,每个 post 最多包含 3 条评论。我目前有这个查询

@posts = Post.includes(:comments)

但这当然会获取所有评论,而不是每个评论只有 3 个。我也想到了这个

@posts = Post.all
@comments = Comment.where(post_id: @posts.ids).limit(3) #this will not apply the limit for each post

我不知道如何在不引起 N+1 查询的情况下执行此操作。

如有任何帮助,我们将不胜感激。

更新

我想我可能需要澄清我的预期结果。我想在 posts 上执行一个 activerecord 查询,它将急切地为每个 post 加载三个评论。这样我得到:

3 条关于 ID 为 1 的 post 的评论 post 有 3 条评论,id 为 2 等等。这可能不会导致 N+1 查询吗?最简单但不受欢迎的解决方案是:

@posts.each {|post| post.comments.limit(3)}

这会给我想要的结果,但会为每个 post.

执行查询

更新 已接受的答案允许您对关联应用任何类型的查询条件,但在使用 includes 时将忽略此条件。这意味着我仍然会将所有评论加载到内存中,从而浪费内存资源。我更喜欢另一种解决方案,但似乎没有办法在这里实现完美的解决方案。

尝试以下

@comments = Comment.where('post_id IN (?)', @posts.ids).limit(3) 

您可以在 post 模型中添加一个新关联,该关联将仅获取 3 条评论记录

has_many :recent_comments, -> { limit(3) }, class_name: 'Comment'

并在控制器中

@post = Post.includes(:recent_comments)

它不会生成 n + 1 个查询。