LaravelMigrationDatabaseMenengah5 mnt baca

Migration: Version Control untuk Database

Buat dan jalankan migration: skema database sebagai kode.

Konsep: Git untuk Database

Bayangkan kamu dan dua teman mengerjakan satu aplikasi. Temanmu menambah kolom harga ke tabel produks lewat phpMyAdmin di laptopnya. Tabel di laptopmu tidak ikut berubah, aplikasimu error, dan tidak ada yang tahu persis apa yang diubah. Kekacauan klasik.

Migration menyelesaikan ini dengan menjadikan skema database sebagai kode. Setiap perubahan struktur (bikin tabel, tambah kolom) ditulis sebagai file PHP di database/migrations, di-commit ke Git seperti kode biasa, dan dijalankan dengan php artisan migrate di laptop siapa pun atau di server mana pun. Hasilnya: semua environment punya struktur database yang identik, dan setiap perubahan tercatat rapi seperti commit Git.

Contoh 1: Membuat dan Menjalankan Migration

bash
php artisan make:migration create_posts_table

Perintah ini membuat file seperti database/migrations/2026_10_08_120000_create_posts_table.php (timestamp di depan memastikan urutan eksekusi). Isi dengan definisi tabel:

File: database/migrations/2026_10_08_120000_create_posts_table.php

php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

up() dijalankan saat migrate, down() saat rollback. Lalu:

bash
php artisan migrate

Laravel mencatat migration yang sudah jalan di tabel migrations, jadi file yang sama tidak akan dijalankan dua kali.

Contoh 2: Relasi dan Tipe Kolom yang Sering Dipakai

File: database/migrations/2026_10_08_120100_create_comments_table.php

php
return new class extends Migration {
    public function up(): void
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('post_id')->constrained()->cascadeOnDelete();
            $table->string('nama', 100);
            $table->text('isi');
            $table->boolean('disetujui')->default(false);
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('comments');
    }
};

foreignId('post_id')->constrained() membuat kolom unsigned bigint plus foreign key ke tabel posts. cascadeOnDelete() berarti komentar ikut terhapus kalau post-nya dihapus. Tipe umum lain: integer(), decimal(10, 2) untuk uang, date(), timestamp(), json().

Jebakan Umum

1. Mengedit migration yang sudah dijalankan. Migration yang sudah masuk tabel migrations tidak akan jalan lagi walau filenya diubah. Solusinya: buat migration baru untuk perubahannya (lihat modul migration-modifikasi), atau rollback dulu baru edit, baru migrate lagi.

2. Lupa menulis down(). Tanpa down() yang benar, migrate:rollback gagal membatalkan perubahan. Untuk Schema::create, pasangannya Schema::dropIfExists. Selalu tulis keduanya.

3. Mengubah database production manual. Godaan terbesar: "cuma tambah satu kolom, langsung via phpMyAdmin saja". Jangan. Perubahan itu tidak tercatat, tidak bisa diulang di server lain, dan tidak bisa di-rollback. Selalu lewat migration, tanpa kecuali.

Catatan teknis: Nama file migration harus unik dan berurutan berdasarkan timestamp. Kalau dua developer membuat migration di waktu yang sama persis, Laravel akan protes saat migrate. Di Laravel 11+, migration memakai anonymous class (return new class extends Migration), jadi tidak ada lagi masalah nama class bentrok.

Tantangan

Tabel Kategori

Buat migration create_categories_table dengan kolom: id, name (string, unique), description (text, nullable), timestamps. Jalankan migrate dan verifikasi tabelnya via tinker (Schema::hasTable('categories')).