ActiveRecord associations: has_one/through
This course covers how ActiveRecord associations are declared, using models from this app. It starts with belongs_to, the side that holds the foreign key, and has_many, the side that returns a collection. It then covers has_one, which returns one record or nil. The options foreign_key, class_name, optional and dependent handle cases where the Rails defaults don't fit. The last lessons cover has_many :through and has_one :through, which reach a third model across a middle one, and the source option for mismatched names.
What you'll learn
- ✓Declaring belongs_to and why Rails 8 makes it required by default
- ✓Using has_many to return a collection and build records through it
- ✓Using has_one for a single record and its generated create_ methods
- ✓Setting foreign_key, class_name, optional and dependent when defaults don't fit
- ✓Reaching a third model with has_many :through and the source option
- ✓Using has_one :through to reach one record across a middle model
belongs_to: the side that holds the foreign key
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.
Read the full lesson free →Curriculum
7 lessonsbelongs_to: the side that holds the foreign key
How belongs_to marks the table holding the foreign key, and why Rails 8 makes it required.
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.
has_one: exactly one, not a collection
How has_one returns one record or nil, generates create_ methods, and leaves uniqueness to indexes or validations.
Naming options: foreign_key, class_name, and optional
Using foreign_key, class_name, optional: true and dependent: :nullify when an association doesn't follow Rails defaults.
has_many :through: skipping the middle table
How has_many :through reaches badges across a join model, and when the source option is needed.
has_one :through: the same idea, one record at a time
A Supplier, Account and AccountHistory example showing has_one :through returning one record or nil.
Putting it together: the full declaration toolkit
A review of every declaration and option from the course, all from this app's models except the has_one :through example.