belongs_to: the side that holds the foreign key
A line from this app's code
module Catalog
class Lesson < ApplicationRecord
belongs_to :course, class_name: "Catalog::Course", touch: true
end
end
This is from app/models/catalog/lesson.rb, word for word. Every lesson this app shows you belongs to one course, and this line is what makes lesson.course return that course instead of raising NoMethodError. The touch: true option updates the course's updated_at whenever the lesson is saved.
Querying was covered, declaring wasn't
The last lesson of SQL: JOIN fundamentals, "JOINs in Rails: ActiveRecord associations", covered joins, includes, eager_load, preload and the N+1 problem in depth, with lines like Catalog::Course.joins(:lessons). It never explained how :lessons or :course came to exist as names you can pass to joins(...). This course fills that gap. It shows how belongs_to, has_many and has_one are written, and ends with the two :through variants in its title.
What belongs_to declares
belongs_to :course means this table, lessons, holds a foreign key column that points at another table, courses. The schema shows it:
lessons table:
course_id bigint <- the foreign key
title jsonb
position integer
course_id is a plain column holding a courses.id value. belongs_to :course turns that integer into lesson.course, a Catalog::Course instance, loaded with its own query the first time you ask for it.
Required by default
Rails.application.config.active_record.belongs_to_required_by_default
# => true
This is this app's own config. In Rails 8, a plain belongs_to :course makes course required. Saving a lesson without a course_id fails validation before anything reaches the database, the same instinct behind save! raising on bad data instead of writing a broken row. A scratch table with the same shape showed it: a lesson without a course failed with Validation failed: Scratch course must exist, not with a database error.
Where the course goes
This lesson covered the job of belongs_to: saying which side holds the foreign key. Lesson 2 covers the other side, has_many. Lesson 3 covers has_one, the single-record version of the same idea. Lesson 4 covers the options for when the defaults don't fit: foreign_key, class_name and optional. Lessons 5 and 6 reach the subject in the title, has_many :through and has_one :through, two ways to reach a third model across a middle one. Lesson 7 ties them together.
Key takeaways
belongs_to :course, copied from this app'sCatalog::Lesson, means this table holds the foreign key column,course_id, pointing at another table.- This app's config confirms that Rails 8 makes a plain
belongs_torequired by default, and a scratch table without a course failed validation as expected. - This course teaches declaring associations. Querying them with
joins,includesand the rest is covered in the lesson "JOINs in Rails: ActiveRecord associations" of SQL: JOIN fundamentals.
Keep going with lesson 2
has_many: the side with the collection
How has_many returns a Relation of child rows, with dependent: :destroy and build filling the foreign key.
A free account also gives you the quizzes, your progress and notes, and the discussion.