Is there a way to avoid the n+1 problem when eager loading and also applying a limit to the subquery? I want to avoid lots of sql queries like this:
Category.all.each do |category|
category.posts.limit(10)
end
But I also want to only get 10 posts per category, so the standard eager loading, which gets all the posts, does not suffice:
Category.includes(:posts).all
What is the best way to solve this problem? Is N+1 the only way to limit the amount of posts per category?
From the Rails docs
So given the following model definition
Calling
Category.find(1).included_posts
would work as expected and apply the limit of 10 in the query. However, if you try to doCategory.includes(:included_posts).all
thelimit
option will be ignored. You can see why this is the case if you look at the SQL generated by an eager loadIf 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)
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.