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 个查询。
我需要帮助生成对集合的子项应用限制的查询。这是我的问题的简单演示。
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 个查询。