I have a simple rails 3 blog app where posts have many comments and comments belong to a post.
I want to create a scope that will fetch all posts that have more than 5 comments. What's the best way of doing this without a counter cache column.
You are looking the offset for your comment, you know it should be between 0 (lower bound) and the number of comments (upper bound, In this case 1 000 000). Offset 0 means the newest post and 1000000 is the oldest post (in this case). Let L denote the lower bound of offset, U denote the upper bound and M half way between L and U. (M = (L + U)/2)
Look at the time on the comment there and compare it to the time of your post. If your post is older, then the offset is to low. Let U = M and calculate a new M. If your post is newer, then the offset is to high. Let L = M and calculate a new M. If your post is from almost the same time, just press "Show more" until you find yours.
The key is that found_posts was confussing me. I thougth that, that number is the posts retrieved but is not. It is the number of posts that match the criteria. It's like the WP_Query had 2 parts: one for finding (all) the posts, and other for fetching the content, when it checks for the pagination parameters.
There is an undocumented parameter called no_found_rows which uses boolean values which you can use to make your query bail after it found the 5 posts you need. This will force WP_Query not to look for any more posts mathing the criteria after it has retrieved the amount of posts queried.
Like this, perhaps?
Post.select('posts.*, count(comments.id) as comment_count').
joins(:comments).
group('posts.id').
having('comment_count > 5')
In Postgres 9.1 I had to set things up like this as postgres isn't happy putting conditions on calculated fields or something like that.
Post.select('posts.*, count(comments.id) as comment_count').
joins(:comments).
group('posts.id').
having('count(comments.id) > 5')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With