ruby 28 lines · 7 steps

How Rails models wire up associations

A Product and Category pair shows how Active Record associations, validations, scopes, and helpers fit together.

Explained by highlit
1class Product < ApplicationRecord
2 belongs_to :category, touch: true
3 
4 has_many :reviews, dependent: :destroy
5 
6 validates :name, presence: true
7 validates :price_cents, numericality: { greater_than: 0 }
8 
9 scope :published, -> { where(published: true) }
10 
11 def average_rating
12 reviews.average(:rating)&.round(1) || 0.0
13 end
14 
15 def formatted_price
16 Money.new(price_cents, currency).format
17 end
18end
19 
20class Category < ApplicationRecord
21 has_many :products, dependent: :restrict_with_error
22 
23 validates :name, presence: true, uniqueness: true
24 
25 def cache_key_with_products
26 "#{cache_key_with_version}/products-#{products.count}"
27 end
28end
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1Association options like touch and dependent encode cascade and cache behavior declaratively instead of in callbacks.
  2. 2Instance methods on a model are the right home for derived values that combine associated data.
  3. 3Pairing dependent: :destroy on one side with :restrict_with_error on the other defines clear deletion rules across the relationship.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How Rails models wire up associations — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code