如何在Rails中通过两层has_many关联查询全部对象
优化两层has_many关联的查询方案
首先先修正你的模型代码里的小错误:Comment 模型的 belongs_to 应该是单数 :post,而不是复数 :posts,正确代码如下:
class Comment < ApplicationRecord belongs_to :post end
接下来提供两种更优的实现方式,都能避免两次查询的开销:
方式一:通过 has_many :through 建立间接关联
在 Blog 模型中直接定义与 Comment 的关联,后续就可以像调用直接关联一样获取数据:
class Blog < ApplicationRecord has_many :posts has_many :comments, through: :posts end
使用时直接调用:
blog = Blog.find(2) blog.comments # 一次SQL查询即可获取所有关联评论
这种方式的优势是代码简洁直观,Rails会自动生成优化的关联查询SQL,避免N+1问题,同时后续复用性高。
方式二:使用关联查询(joins)直接过滤
如果不想修改模型关联,也可以通过一次关联查询直接获取结果:
blog = Blog.find(2) Comment.joins(post: :blog).where(blogs: { id: blog.id })
或者更简洁的写法:
Comment.joins(post: :blog).where(blogs: blog)
这种方式同样只会发起一次SQL查询,通过JOIN关联三张表,直接过滤出属于指定Blog的评论,性能和第一种方式相近。
对比原方案的优势
你原来的方案会发起两次SQL查询:第一次查询该Blog下所有Post的ID,第二次通过Post ID查询评论。而上面两种方式都只需要一次查询,在数据量较大时能明显提升性能,同时代码更简洁易维护。
内容的提问来源于stack exchange,提问作者John Hinnegan
相关产品推荐
相关产品推荐

