Reputation: 834
I have below table structure. This is just an example
UserPost => user_id, post_id, Post, Comment
So, If I try to fetch all user_posts
using the below query and do where on the comments
table then it fires query for the comments
table
user_posts = UserPost.includes(post: :comments)
user_posts.each do |up|
post = up.post # No Query
comments = up.comments # No query
comments_with_condition = up.comments.where(visibility: true).order(position: :asc).first.data # Fires query for .where and .order as well.
end
So, is this the expected behavior or I am doing something wrong?
How to prevent the query for each user_post
Upvotes: 2
Views: 956
Reputation: 14900
What you can do is add another has_many
to your model with a filter of what you want.
# You can name this anything you want but a descriptive name helps
has_many :special_comments, -> { where(visibility: true).order(..) }, class_name: 'Comment'
...and eager load that in your query which will eager load both type of comments. This will inevitably lead to one extra query, but it is not N+1.
user_post = UserPost.includes(post: [:comments, :special_comments])
user_posts.each do |user_post|
post = user_post.post
comments = user_post.comments
comments_with_condition = user_post.special_comments
end
Upvotes: 3