Associations
has_many and belongs_to.
Associations is a free Ruby Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Ruby Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Are Associations?
Associations declare relationships between models so Active Record can navigate related rows for you. Instead of writing join SQL, you call methods like user.posts.
- They mirror the foreign keys in your database.
- They generate helper methods automatically.
- They make code read like the domain.
belongs_to
belongs_to says this model holds a foreign key pointing to another. A Comment that belongs to a Post has a post_id column.
class Comment < ApplicationRecord
belongs_to :post
end
# comment.post returns the parent Post
# Requires a post_id column on commentshas_many
has_many is the other side: one record owns many of another. A Post has many Comment records. The foreign key lives on the many side.
class Post < ApplicationRecord
has_many :comments
end
# post.comments returns all related comments
# post.comments.create(body: "Nice!")Where the Foreign Key Lives
The model that belongs_to holds the foreign key. For Post and Comment, the comments table has post_id. Set this up in a migration with t.references :post or add_reference.
create_table :comments do |t|
t.references :post, foreign_key: true
t.text :body
t.timestamps
endGenerated Methods
A has_many :comments gives you a collection with handy methods:
post.commentsto read.post.comments.create(...)to add a linked record.post.comments.countto count.post.comment_idsfor the ids.
post = Post.find(1)
post.comments.create(body: "First!")
puts post.comments.counthas_one
has_one models a one-to-one link, like a User that has one Profile. The foreign key still lives on the other model (profiles.user_id).
class User < ApplicationRecord
has_one :profile
end
class Profile < ApplicationRecord
belongs_to :user
endMany-to-Many with through
For many-to-many, use a join model and has_many through. A Student has many Course records through Enrollment rows.
class Student < ApplicationRecord
has_many :enrollments
has_many :courses, through: :enrollments
end
class Enrollment < ApplicationRecord
belongs_to :student
belongs_to :course
endDependent Options
Decide what happens to children when a parent is deleted with dependent:
dependent: :destroydeletes children too.dependent: :nullifyclears their foreign key.dependent: :restrict_with_errorblocks deletion.
class Post < ApplicationRecord
has_many :comments, dependent: :destroy
endThe N+1 Query Problem
Looping over records and touching an association can fire one query per record, the dreaded N+1. Loading 10 posts then their comments can run 11 queries instead of 2.
This silently slows applications as data grows.
# N+1: one query per post for comments
Post.all.each do |post|
puts post.comments.count
endFixing N+1 with includes
includes tells Active Record to eager-load the association in a couple of queries instead of many. This is the standard fix for N+1.
Post.includes(:comments).each do |post|
puts post.comments.count
endCustom Names with class_name
When the association name does not match the model, use options like class_name and foreign_key. For example an author association backed by the User model.
class Post < ApplicationRecord
belongs_to :author, class_name: "User"
endQuick Check
Test your understanding of associations.
Recap: Associations
You learned how to relate models:
belongs_toholds the foreign key;has_manyandhas_oneare the other side.has_many throughmodels many-to-many.dependentcontrols cascading deletes.- Avoid N+1 queries with
includes.
Next we ensure data integrity with validations and learn to query.
Frequently asked questions
Is the “Associations” lesson free?
Yes — the full text of “Associations” is free to read here on the web, and the Ruby Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Ruby Academy course, upgrade to CoddyKit PRO.
What will I learn in “Associations”?
has_many and belongs_to. You practise Ruby Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Ruby Academy?
No prior experience is required. Ruby Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Associations” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Ruby Academy lesson?
Yes. Every Ruby Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.