Membedah migrations Rails: membuat dan mengubah tabel lewat DSL migration, bin/rails db:migrate dan rollback, peran schema.rb sebagai sumber kebenaran, seed data, serta praktik schema evolution di production tanpa downtime

Setelah di episode 5 kalian membangun model dengan associations, episode 6 membahas mekanisme di balik perubahan schema: migrations. Model di episode 5 bergantung pada tabel yang dibuat migration — dan di sinilah kita belajar mengendalikan evolusi schema secara aman.
Mengapa migrations penting dikuasai dalam? Karena database adalah aset paling berharga dan paling sulit diubah di sebuah aplikasi. Migration memberi kalian riwayat perubahan yang bisa diuji, di-review, dan di-reverse — berbeda dengan mengubah tabel manual via psql yang tidak meninggalkan jejak. Di production, migration yang baik berarti perubahan schema tanpa downtime dan tanpa data hilang.
Migration adalah file Ruby yang mendeskripsikan perubahan schema secara deklaratif. Saat rails g model dijalankan di episode 5, Rails membuat migration berikut:
class CreatePosts < ActiveRecord::Migration[8.1]
def change
create_table :posts do |t|
t.references :user, null: false, foreign_key: true
t.string :title
t.text :body
t.timestamps
end
end
endt.timestamps membuat created_at dan updated_at yang otomatis dikelola Rails. t.references :user membuat kolom user_id plus foreign key constraint.
bin/rails db:migrate
bin/rails db:migrate:statusdb:migrate menjalankan migration yang belum dieksekusi; db:migrate:status menampilkan tabel riwayat (ada di schema_migrations). Untuk membalik:
bin/rails db:rollback
bin/rails db:rollback STEP=2Agar rollback berfungsi, migration harus reversible. Method DSL Rails (create_table, add_column, add_index) bersifat reversible secara otomatis. Untuk perubahan yang tidak bisa ditebak (misal menghapus data), tulis up/down eksplisit.
Menambah kolom adalah operasi paling umum. Gunakan generator agar file bernama jelas:
bin/rails g migration AddPublishedToPosts published:booleanclass AddPublishedToPosts < ActiveRecord::Migration[8.1]
def change
add_column :posts, :published, :boolean, default: false, null: false
end
endKata kunci penting: default dan null: false. Untuk kolom baru yang akan diisi kemudian, default mencegah error NOT NULL pada baris yang sudah ada. Di production, menambah kolom NOT NULL tanpa default pada tabel besar = risiko downtime.
Setelah migrate, Rails menulis ulang db/schema.rb — representasi lengkap schema saat ini, terlepas dari berapa banyak migration yang telah dijalankan:
create_table "posts", force: :cascade do |t|
t.bigint "user_id", null: false
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "published", default: false, null: false
t.index ["user_id"], name: "index_posts_on_user_id"
endKapan pun kalian butuh snapshot schema (misal menulis query, memahami struktur, atau membangun environment baru), buka schema.rb — bukan psql. Database CI juga di-reset dari file ini, bukan dari menjalankan ulang ratusan migration.
Data awal untuk development dan demo ditulis di db/seeds.rb:
user = User.create!(name: "Rina", email: "rina@example.com")
10.times do |i|
post = user.posts.create!(
title: "Post #{i + 1}",
body: "Isi post #{i + 1}",
published: i.even?
)
post.comments.create!(user: user, body: "Komentar #{i + 1}")
endJalankan dengan:
bin/rails db:seedcreate! (dengan tanda seru) melempar exception jika validasi gagal — memaksa masalah segera terlihat, alih-alih gagal diam-diam.
Di production, migration dijalankan satu per satu dengan deploy bertahap. Prinsip yang menjaga availability:
strong_migrations).Warning
Jangan pernah meng-edit migration yang sudah dieksekusi dan sudah masuk production. Migration adalah riwayat yang tidak boleh diubah; jika butuh penyesuaian, buat migration baru. Ini menjamin setiap environment punya urutan perubahan yang sama.
Alur yang menjaga schema tetap aman dan mudah di-review:
bin/rails g migration AddViewsToPosts views_count:integer
# edit file migration
bin/rails db:migrate
bin/rails db:migrate:status
bin/rails db:schema:dump # (opsional; otomatis saat migrate)Setelah migrate, selalu cek schema.rb di git diff — pastikan hanya berisi perubahan yang kalian inginkan. Migration yang tidak menyentuh schema.rb adalah tanda ia tidak melakukan apa-apa (atau hanya revisi).
db:rollback di development — kalian mengubah schema tanpa mencoba membaliknya; migration tidak testable.add_column terpisah di migration yang sama file — lebih baik satu migration satu perubahan logis agar rollback sederhana.Episode 6 membekali kalian pengelolaan schema Rails: migration sebagai riwayat perubahan yang reversible, db:migrate/db:rollback sebagai kontrolnya, schema.rb sebagai sumber kebenaran saat ini, db/seeds.rb untuk data development, dan prinsip schema evolution yang menjaga production tetap hidup.
Inti yang harus dibawa pulang:
db:migrate, db:rollback, dan db:migrate:status adalah perintah harian.schema.rb = snapshot schema; dipakai CI untuk reset database.Di episode 7 selanjutnya kita akan membedah views & Action View — ERB templates, partials, helpers, layouts, dan Hotwire (Turbo Frames & Turbo Streams) untuk membangun UI tanpa build JS berat. Sampai jumpa di episode 7!