Sanjay Prajapati
Sanjay Prajapati

Reputation: 834

Rails N + 1 query problem when fetching associated records with where condition

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

Answers (1)

Eyeslandic
Eyeslandic

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

Related Questions