ActiveRecord querying: includes & joins
This course covers how ActiveRecord queries related data across tables. It starts with .merge, which reuses a scope from a joined model. It shows why joins with .count returns duplicate rows and how .distinct fixes the count. It covers where.associated and where.missing as named existence filters. It explains eager loading through a has_many :through association and a polymorphic association, including why eager_load raises an error there. It ends with strict_loading, which raises an error instead of running a lazy query, and a scenario that combines every mechanic.
What you'll learn
- ✓Reusing a scope from a joined model with .merge
- ✓Avoiding duplicate rows in aggregates over joins with .distinct
- ✓Filtering by association existence with where.associated and where.missing
- ✓Eager loading has_many :through and polymorphic associations
- ✓Raising on lazy loading with strict_loading
.merge: reusing a scope from the joined model
The lesson "JOINs in Rails: ActiveRecord associations", in SQL: JOIN fundamentals, is thorough. It covers joins (an INNER JOIN that filters and doesn't load), left_joins (a LEFT OUTER JOIN, including anti-joins), and the three loading strategies includes, eager_load and preload. It walks through…
Read the full lesson free →Curriculum
7 lessons.merge: reusing a scope from the joined model
Using .merge to reuse the active scope of Course on a joined relation, producing the same SQL as where.
The joins + .count trap: duplicate rows from the JOIN
Why joins(:lessons).count counts course-lesson pairs, how .distinct.count fixes it, and why includes(:lessons).count skips the JOIN.
where.associated and where.missing: built-in existence filters
Using where.missing and where.associated as named forms of the anti-join and existence filter, with .distinct still needed for counts.
Eager loading through a has_many :through association
Why includes(:badges) on a has_many :through association sends three queries, with one extra for the user_badges join table.
Eager loading a polymorphic association
How includes(:record) sends one query per distinct record_type, and why eager_load raises EagerLoadPolymorphicError on polymorphic associations.
strict_loading: raising instead of being slow
How strict_loading raises StrictLoadingViolationError on lazy association access, while associations preloaded with includes keep working.
Putting it together: every mechanic in one scenario
A badge-progress scenario combining strict_loading, joins with merge, distinct, includes and a :through eager load.