Teori migration sudah kita pahami; sekarang saatnya tangan kita bekerja. Sepanjang sisa Section ini kita membangun skema untuk fitur blog bertahap, dimulai dari tabel posts yang menyimpan artikel. Pada chapter ini kita membuat berkas migration-nya lewat artisan, membaca struktur kelas yang dihasilkan, mengisi skema tabel, lalu menjalankannya dan memverifikasi hasilnya di database. Alur lengkap ini — buat, isi, jalankan, periksa — adalah siklus yang akan kita ulangi seumur hidup proyek.
Membuat Berkas Migration #
Artisan menyediakan perintah make:migration dengan nama migration sebagai argumen. Konvensi penamaan Laravel memakai pola kalimat deskriptif, jadi untuk membuat tabel baru kita menulis create_posts_table:
php artisan make:migration create_posts_tableOutput yang Dihasilkan:
INFO Migration [database/migrations/2026_10_13_170046_create_posts_table.php] created successfully.Perintah tersebut membuat satu berkas PHP di database/migrations. Nama berkasnya terdiri dari tiga bagian: timestamp 2026_10_13_170046 (13 Oktober 2026, pukul 17:00:46), nama deskriptif create_posts_table, dan ekstensi .php. Timestamp inilah yang menentukan urutan eksekusi — migration yang dibuat lebih dulu selalu dijalankan lebih dulu, sebagaimana kita bahas pada chapter Konsep Migration. Laravel juga membaca nama deskriptifnya: pola create_*_table membuat stub siap membentuk tabel posts, dan dokumentasi migrations
mencantumkan pola-pola lain yang dikenali seperti add_*_to_*_table.
Anatomi Kelas Anonymous #
Mari kita buka berkas yang barusan dibuat dan lihat isinya persis apa adanya:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('posts');
}
};Struktur kunci yang perlu dicermati:
- Baris
return new class extends Migrationmengembalikan anonymous class — kelas tanpa nama yang mewarisiIlluminate\Database\Migrations\Migration. Sejak Laravel versi 9, inilah gaya bawaan stub migration, dan Laravel 13 tetap menggunakannya. Anonimitas kelas mencegah bentrokan nama kelas ketika dua migration dari cabang Git berbeda ternyata memakai nama kelas yang sama. - Method
up()berisi operasi yang diterapkan ketika migration dijalankan. - Method
down()berisi kebalikannya, dijalankan saat migration dibatalkan lewatmigrate:rollback— detailnya kita bahas tuntas pada chapter Migration Rollback.
Stub sudah menebak benar bahwa kita hendak membuat tabel, jadi Schema::create('posts', ...) dan Schema::dropIfExists('posts') sudah terisi. Tugas kita tinggal menambahkan kolom.
Mengisi Skema Tabel posts #
Kita lengkapi method up() dengan kolom-kolom yang dibutuhkan sebuah artikel blog:
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title', 150);
$table->text('body');
$table->timestamps();
});
}Mari kita bedah tiap barisnya. $table->id() membuat kolom id bertipe integer besar dengan auto-increment dan primary key — kolom identitas standar tabel Laravel. $table->string('title', 150) membuat kolom title bertipe varchar dengan panjang maksimal 150 karakter, cukup untuk judul artikel. $table->text('body') membuat kolom body bertipe text yang muat isi artikel panjang tanpa batas praktis. Terakhir, $table->timestamps() membuat dua kolom sekaligus — created_at dan updated_at — yang dikelola otomatis oleh Eloquent setiap kali baris dibuat atau diubah.
Method down() tidak perlu disentuh: Schema::dropIfExists('posts') sudah menjadi kebalikan yang sempurna — hapus tabel bila ada, diam bila tidak ada. Daftar lengkap tipe kolom jauh lebih beragam dari keempat method ini, dan kita petakan satu per satu pada chapter Column Types.
Menjalankan Migration #
Saatnya menerapkan skema ke database:
php artisan migrateOutput yang Dihasilkan:
INFO Running migrations.
2026_10_13_170046_create_posts_table ........................... 1.74ms DONELaravel membandingkan isi database/migrations dengan tabel migrations, menemukan 2026_10_13_170046_create_posts_table belum tercatat, lalu menjalankan method up()-nya. Migration yang sudah berjalan duluan — termasuk pembuat tabel users, cache, dan jobs — tidak muncul di output karena sudah tercatat di tabel migrations.
Memeriksa Hasil dan Status #
Dua perintah pemeriksaan menutup siklus ini. Yang pertama menampilkan struktur tabel hasil migration:
php artisan db:table postsOutput yang Dihasilkan:
main.posts .................................................................
Columns .................................................................. 5
Column ................................................................ Type
id integer, autoincrement .......................................... integer
title varchar ...................................................... varchar
body text ............................................................. text
created_at datetime, nullable ..................................... datetime
updated_at datetime, nullable ..................................... datetime
Index ......................................................................
primary id ......................................................... primary Kelima kolom yang kita definisikan hadir sesuai urutan, lengkap dengan atribut tipe dan nullability-nya. Perintah kedua menampilkan status seluruh migration:
php artisan migrate:statusOutput yang Dihasilkan:
Migration name .............................................. Batch / Status
0001_01_01_000000_create_users_table ............................... [1] Ran
0001_01_01_000001_create_cache_table ............................... [1] Ran
0001_01_01_000002_create_jobs_table ................................. [1] Ran
2026_10_13_153049_create_personal_access_tokens_table .............. [1] Ran
2026_10_13_170046_create_posts_table ............................... [2] Ran Kolom Batch menunjukkan pengelompokan eksekusi: empat migration pendahulu berjalan lewat satu perintah di masa lalu (batch 1), sedangkan create_posts_table berjalan lewat perintah kita barusan (batch 2). Nomor batch ini kelak menjadi patokan ketika kita membatalkan migration.
Satu minggu kemudian kebutuhan hampir pasti berubah: kolom baru dibutuhkan, nama kolom terasa kurang tepat. Pertanyaannya — apakah kita mengedit migration yang sudah dijalankan ini? Jawabannya tegas tidak, dan alasan serta solusinya adalah bahasan chapter Mengubah Struktur Tabel.