0
0
RailsComparisonBeginner · 4 min read

Joins vs Includes in Rails: Key Differences and When to Use Each

In Rails, joins performs an SQL INNER JOIN to combine tables and filter results at the database level, while includes uses eager loading to preload associated records and avoid N+1 queries. Use joins when you want to filter or sort by associated table columns, and includes when you want to load associations efficiently without filtering.
⚖️

Quick Comparison

This table summarizes the main differences between joins and includes in Rails.

Factorjoinsincludes
PurposeCombine tables for filtering or sortingEager load associations to avoid N+1 queries
SQL BehaviorGenerates INNER JOIN SQLGenerates separate queries or LEFT OUTER JOIN
When to UseFilter or sort by associated table columnsLoad associated records for later use
PerformanceSingle query with join, faster filteringMultiple queries or LEFT OUTER JOIN, reduces N+1 queries
Result TypeReturns records matching join conditionsReturns all main records with preloaded associations
⚖️

Key Differences

joins creates an SQL INNER JOIN between tables, which means it only returns records that have matching associated records. This is useful when you want to filter or sort based on columns in the associated table. For example, finding users who have posts with a certain title.

On the other hand, includes is designed to eager load associations to avoid the N+1 query problem. It loads the main records and their associated records in separate queries or sometimes with a LEFT OUTER JOIN, so all main records are returned regardless of whether they have associated records.

While joins focuses on filtering and combining tables in one query, includes focuses on loading associated data efficiently for later use in your code without extra queries.

⚖️

Code Comparison

Example: Find users who have posts with the title 'Hello'.

ruby
User.joins(:posts).where(posts: { title: 'Hello' })
Output
[#<User id: 1, name: "Alice">, #<User id: 3, name: "Charlie">]
↔️

Includes Equivalent

Example: Load users and their posts to avoid N+1 queries when accessing posts.

ruby
users = User.includes(:posts).where(name: 'Alice')
users.each do |user|
  puts user.posts.map(&:title)
end
Output
["Hello", "Rails Tips"]
🎯

When to Use Which

Choose joins when you need to filter, sort, or query based on columns in associated tables because it performs an INNER JOIN and returns only matching records.

Choose includes when you want to load associated records upfront to avoid multiple database queries (N+1 problem), especially when you will access those associations later in your code.

Using includes without filtering on associated tables is best for performance when you just need the related data loaded.

Key Takeaways

joins performs INNER JOIN for filtering and sorting by associated table columns.
includes eager loads associations to avoid N+1 queries by loading related records upfront.
Use joins when filtering on associated data; use includes when just loading associations.
joins returns only records with matching associations; includes returns all main records with preloaded associations.
Choosing the right method improves query performance and avoids unnecessary database calls.