0
0
RailsHow-ToBeginner · 4 min read

How to Use includes in Rails for Efficient Queries

In Rails, use includes to preload associated records and avoid N+1 query problems. It loads related data in fewer queries, improving performance when accessing associations.
📐

Syntax

The includes method is called on an ActiveRecord query to preload associations. It takes one or more association names as symbols or arrays.

  • Model.includes(:association) loads the specified association.
  • You can pass multiple associations like includes(:assoc1, :assoc2).
  • It returns an ActiveRecord::Relation that fetches associated records efficiently.
ruby
Model.includes(:association_name)
💻

Example

This example shows how to use includes to preload comments when fetching posts, avoiding extra queries when accessing comments.

ruby
class Post < ApplicationRecord
  has_many :comments
end

class Comment < ApplicationRecord
  belongs_to :post
end

# Fetch posts with comments preloaded
def fetch_posts_with_comments
  posts = Post.includes(:comments).limit(3)
  posts.each do |post|
    puts "Post: #{post.title}"
    post.comments.each do |comment|
      puts "- Comment: #{comment.body}"
    end
  end
end

fetch_posts_with_comments
Output
Post: First Post - Comment: Great post! - Comment: Thanks for sharing. Post: Second Post - Comment: Interesting read. Post: Third Post - Comment: Nice article.
⚠️

Common Pitfalls

Common mistakes when using includes include:

  • Using includes but then filtering on the included association in a way that triggers extra queries (use references or joins for conditions).
  • Expecting includes to always eager load; sometimes Rails falls back to lazy loading if conditions are not met.
  • Not using includes when accessing associations in loops, causing N+1 queries.
ruby
# Wrong: causes N+1 queries
posts = Post.all
posts.each do |post|
  puts post.comments.count
end

# Right: preloads comments to avoid N+1
posts = Post.includes(:comments).all
posts.each do |post|
  puts post.comments.count
end
📊

Quick Reference

UsageDescription
Model.includes(:assoc)Preloads the association to avoid N+1 queries
Model.includes(:assoc1, :assoc2)Preloads multiple associations
Model.includes(:assoc).where(assoc: { attr: value })Use with references or joins for conditions on associations
Model.joins(:assoc)Joins tables but does not preload associations
Model.eager_load(:assoc)Forces eager loading with LEFT OUTER JOIN

Key Takeaways

Use includes to preload associations and avoid N+1 query problems.
Pass association names as symbols to includes for efficient loading.
Combine includes with references or joins when filtering on associations.
Without includes, accessing associations in loops causes many extra queries.
Check query logs to confirm includes is working as expected.