For example I have a blog object, and that blog has many posts. I want to do eager loading of say the first blog object and include say the first 10 posts of it. Currently I would do @blogs = Blog.limit(4)
and then in the view use @blogs.posts.limit(10)
. I am pretty sure there is a better way to do this via an include such as Blog.include(:posts).limit(:posts=>10)
. Is it just not possible to limit the number of included objects, or am I missing something basic here?
Asked
Active
Viewed 4,358 times
16
-
See http://stackoverflow.com/questions/6076392/limit-the-number-of-objects-returned-in-a-has-many – Thilo Jul 16 '11 at 20:07
-
Odd, I can't even get this approach to work in the Rails(3.1) console. added `has_many :recent_posts, :class_name => 'Post', :limit => 3`. But when I do `Blog.includes(:posts).first` I still got all the posts not just the first 3. – loneaggie Jul 16 '11 at 23:36
-
Try Blog.includes(:recent_posts).first.recent_posts – Thilo Jul 17 '11 at 04:43
-
You're right, it doesn't work for me either. The limit is not applied to the query for posts. Odd. – Thilo Jul 17 '11 at 04:50
2 Answers
10
Looks like you can't apply a limit to :has_many
when eager loading associations for multiple records.
Example:
class Blog < ActiveRecord::Base
has_many :posts, :limit => 5
end
class Post < ActiveRecord::Base
belongs_to :blog
end
This works fine for limiting the number of posts for a single blog:
ruby-1.9.2-p290 :010 > Blog.first.posts
Blog Load (0.5ms) SELECT `blogs`.* FROM `blogs` LIMIT 1
Post Load (0.6ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`blog_id` = 1 LIMIT 5
However, if you try to load all blogs and eager load the posts with them:
ruby-1.9.2-p290 :011 > Blog.includes(:posts)
Blog Load (0.5ms) SELECT `blogs`.* FROM `blogs`
Post Load (1.1ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`blog_id` IN (1, 2)
Note that there's no limit on the second query, and there couldn't be - it would limit the number of posts returned to 5 across all blogs, which is not at all what you want.
EDIT:
A look at the Rails docs confirms this. You always find these things the minute you've figured them out :)
If you eager load an association with a specified :limit option, it will be ignored, returning all the associated objects

Thilo
- 17,565
- 5
- 68
- 84
2
You need to limit the number of posts in your blog model like this:
class Blog < ActiveRecord::Base
has_many :included_posts, :class_name => 'Post', :limit => 10
has_many :posts
end
So then you can do:
$ Blog.first.included_posts.count
=> 10
$ Blog.first.posts.count
=> 999

thenengah
- 42,557
- 33
- 113
- 157
-
-
-
I see how that works, but is it possible to also get the blog object back within the query? `@blogs = Blog.limit(3).recent_posts` actually gives me an array of Posts, but not the initial parent Blog. I'm trying to optimize my db/query usage if that makes any sense. – loneaggie Jul 16 '11 at 20:22
-
1