Look for an attribute in an eager loded subsection of a subsection, without causing a SQL call?

15 Views Asked by At

I have a set of models like below (the actual setup displayed here is a simplified mockup):

Blog 
has_many :posts

Post
has_many :comments
# contributor_id is a part of Post

Contributor
# having fields such as :id, :name, etc. 

I iterate through them like this:

Blog.all.includes(:posts => :contributors).each do |blog|
render partial: 'blog_item', :locals => { :blog => blog } 
end

Inside 'blog_item' partial view I would like to determine whether a specific Contributor (id: 123, name:"john") is included among the posts. As a general problem it is quite easy, but I want to do this without having an SQL call (causing N+1).

Currently, I am solving this like so:

blog.posts.pluck(:contributor_id).include?(123)

which causes an SQL call (and subsequently an N+1).

I can't do something like this:

blog.posts.include?(:contributor_id) 

So, how can this be solved without having that extra SQL call?

1

There are 1 best solutions below

0
Christoffer On

I have been trying to solve this for quite some time. Posted the question, read a subsection of an article directly after and solved it in 2 mins.

@contributor = Contributor.find(123)
Blog.all.includes(:posts => :contributors).each do |blog|
  render partial: 'blog_item', :locals => { :blog => blog } 
end

# Inside blog_item
blog.posts.map(&:contributor).include?(@contributor)