Associations
Real apps are made of related data: authors and books, posts and comments, doctors and patients. Rails associations let you describe those relationships once and get a rich set of helper methods for free.
Learn Associations in our free Ruby course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Ruby course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll wire up has_many, belongs_to, has_many :through, and has_and_belongs_to_many, and understand foreign keys and dependent: :destroy.
What You'll Learn in This Lesson
1️⃣ One-to-Many: has_many and belongs_to
The most common association is one-to-many. The "one" side declares has_many ; the "many" side declares belongs_to and holds the foreign key column ( author_id ). Add dependent: :destroy so children don't outlive their parent.
2️⃣ Many-to-Many: :through and HABTM
When records relate on both sides, use a many-to-many . Prefer has_many :through when the join needs its own data; reach for has_and_belongs_to_many only for a plain link with nothing extra to store.
Your turn. Complete a blog's Post and Comment models so the one-to-many works end to end.
Model tags with has_many :through : a Post and a Tag joined by a Tagging . Write all three model classes.
📋 Quick Reference — Associations
Practice quiz
Which association declares that one Author has many Books?
- belongs_to :books
- has_many :books
- has_one :books
- habtm :books
Answer: has_many :books. has_many :books goes in the Author model to express the one-to-many side.
On which model does the foreign key column normally live?
- The model that declares has_many
- Neither model — it is in a join file
- The model that declares belongs_to
- Always the Author model
Answer: The model that declares belongs_to. The belongs_to side holds the foreign key, e.g. books.author_id.
Following Rails conventions, what is the foreign key column for Book belongs_to :author?
- books_author
- author_key
- id_author
- author_id
Answer: author_id. Rails expects a column named author_id by convention.
What does dependent: :destroy do on has_many?
- Prevents deleting the parent
- Deletes associated child records when the parent is destroyed
- Marks children as archived
- Renames the foreign key
Answer: Deletes associated child records when the parent is destroyed. dependent: :destroy removes the children (running their callbacks) when the parent is destroyed.
Which association is used for a many-to-many relationship WITH a join model you can add attributes to?
- has_one
- belongs_to
- has_many :through
- has_and_belongs_to_many
Answer: has_many :through. has_many :through uses an explicit join model, so the join can carry its own columns.
has_and_belongs_to_many (HABTM) requires what in the database?
- A join table with no model
- A single foreign key
- Two separate tables only
- A polymorphic column
Answer: A join table with no model. HABTM uses a join table (e.g. authors_books) with no dedicated model class.
For a Comment that belongs to a Post, what does post.comments return?
- A single Comment
- An ActiveRecord relation of that post's comments
- The post's id
- nil unless cached
Answer: An ActiveRecord relation of that post's comments. has_many gives a collection (relation) of the associated records.
Which line belongs in the Book model for a one-to-many with Author?
- has_many :author
- has_one :author_id
- references :author
- belongs_to :author
Answer: belongs_to :author. The child (Book) declares belongs_to :author.
In a has_many :through, what must the through model itself declare?
- Only validations
- has_many to both sides
- Nothing special
- belongs_to to BOTH joined models
Answer: belongs_to to BOTH joined models. The join model uses belongs_to to each of the two models it connects.
What does inverse_of help Rails do?
- Reverse a migration
- Recognise the two sides of an association point at the same in-memory object
- Delete records faster
- Validate uniqueness
Answer: Recognise the two sides of an association point at the same in-memory object. inverse_of tells Rails the two association ends are the same object, avoiding redundant queries.