Creating Models, Migrations and Data Types
Bookclub needs to remember books. In Rails that means two things that always travel together: a table in the database and a model class that reads and writes it. Migrations are how the table comes into being and how it changes over time.
The rule
One model, one table; change the table only through migrations.
bin/rails generate model Book title:string author:string pages:integer \
price:decimal published_on:date available:booleanThis writes app/models/book.rb:
class Book < ApplicationRecord
endand a migration in db/migrate/:
class CreateBooks < ActiveRecord::Migration[8.0]
def change
create_table :books do |t|
t.string :title
t.string :author
t.integer :pages
t.decimal :price, precision: 8, scale: 2 # precision and scale added by hand
t.date :published_on
t.boolean :available, default: true # default added by hand
t.timestamps # created_at, updated_at
end
end
endbin/rails db:migrate runs it. Rails adds an id primary key automatically, and t.timestamps adds created_at and updated_at, which Rails fills in for you. The empty class already knows every column: Book.new(title: "Dune").title works because Active Record reads the table.
Naming is by convention: model Book (singular, CamelCase) ↔ table books (plural, snake_case).
Common data types:
| Type | Use for |
|---|---|
string |
short text: titles, names, emails |
text |
long text: review bodies |
integer |
whole numbers: pages, ratings |
decimal |
exact numbers: money |
float |
approximate numbers: measurements |
boolean |
yes or no |
date / datetime |
a day / a moment |
references |
a foreign key such as book_id |
Later changes are new migrations: bin/rails g migration AddIsbnToBooks isbn:string. bin/rails db:rollback undoes the last one.
The shortcut
For each field, ask "what will I do with it?" Add money → decimal. Sort by day → date. Count it → integer. Read it as a paragraph → text. The type follows the use, not how the value looks.
Rating
Compared and averaged, whole numbers 1 to 5:
integer.
The trap is editing an old migration after others have run it. Their databases will never see the change. Write a new migration.
Drills
Answer fast — trust the rule.
Which table does the model BookClubEvent use by default?
Which type should store a book's price?
Which columns does t.timestamps add?
You need an isbn column on an app whose first migration teammates already ran. What do you do?
Remember
- One model, one table; change the table only through migrations.
- Shortcut: pick the type by what you will do with the value.
- Trap: editing old migrations or schema.rb instead of adding a migration.
