Rails 4 Eager load limit subquery

馋奶兔 提交于 2019-12-06 05:27:36

From the Rails docs

If you eager load an association with a specified :limit option, it will be ignored, returning all the associated objects

So given the following model definition

class Category < ActiveRecord::Base
  has_many :posts
  has_many :included_posts, -> { limit 10 }, class_name: "Post"
end

Calling Category.find(1).included_posts would work as expected and apply the limit of 10 in the query. However, if you try to do Category.includes(:included_posts).all the limit option will be ignored. You can see why this is the case if you look at the SQL generated by an eager load

Category.includes(:posts).all

Category Load (0.2ms)  SELECT "categories".* FROM "categories"
Post Load (0.4ms)  SELECT "posts".* FROM "posts" WHERE "posts"."category_id" IN (1, 2, 3)

If you added the LIMIT clause to the posts query, it would return a total of 10 posts and not 10 posts per category as you might expect.

Getting back to your problem, I would eager load all posts and then limit the loaded collection using first(10)

categories = Category.includes(:posts).all
categories.first.posts.first(10)

Although you're loading more models into memory, this is bound to be more performant since you're only making 2 calls against the database vs. n+1. Cheers.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!