Eager Loading Polymorphic Associations in Ruby on Rails
For when .includes
is not enough.
Basic Rails Associations
Rails’ ActiveRecord associations permits relating one model to another. Take the example below:
class Post < ApplicationRecord
has_many :comments
endclass Comment < ApplicationRecord
belongs_to :post
end
A Post
has many Comments
. This allows us to call Post.first.comments
to get all the comments associated with a post! ActiveRecord internally generates our required SQL queries:
SELECT "posts".* FROM "posts" WHERE "posts".id = 1
SELECT "comments".* FROM "comments" WHERE "comments".post_id
N+1 Queries and .includes
However, imagine we are serializing this data to return as part of a controller for the /posts
index. In that case, instead of getting the comments for just one post, we would get it for multiple posts: Post.all.each { |p| puts p.comments }
. What happens to our SQL queries?
SELECT "posts".* FROM "posts"
SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1
SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 2
...
SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = N