Bab 2 — Migration dan Model
2.1Konsep
Migration = riwayat bentuk tabel
Daripada membuat tabel dengan klik-klik di phpMyAdmin, kita menulis migration: berkas kode yang menjelaskan bentuk tabel. Keuntungannya: bentuk tabel tercatat, bisa diulang di komputer lain, dan semua anggota kelompok punya tabel yang persis sama.
Model = jembatan ke satu tabel
Model Siswa mewakili tabel siswas. Laravel menebak nama tabel dari nama model (Siswa → siswas). Lewat model, kamu menyimpan dan membaca data dengan kode PHP seperti Siswa::all(), tanpa menulis SQL.
$fillable = daftar kolom yang boleh diisi
Saat kamu menulis Siswa::create([...]), Laravel hanya mau mengisi kolom yang tercantum di $fillable. Ini pagar keselamatan: kalau seseorang mengirim isian tambahan yang tidak kamu rencanakan, isian itu diabaikan atau ditolak.
2.2Langkah 1 — Buat model, migration, dan controller sekaligus
Perintah ini membuat tiga berkas sekaligus:
| Opsi | Berkas yang dibuat |
|---|---|
| (model) | app/Models/Siswa.php |
-m |
database/migrations/xxxx_create_siswas_table.php |
-c -r |
app/Http/Controllers/SiswaController.php, berisi kerangka method CRUD |
Buka folder proyek di VS Code dan temukan ketiga berkas itu sebelum lanjut. Nama berkas migration diawali tanggal dan jam, jadi berbeda di tiap komputer. Itu wajar.
2.3Langkah 2 — Isi migration
Buka berkas migration yang baru dibuat. Di dalamnya ada method up() (membuat tabel) dan down() (membatalkannya). Ganti isi method up() dengan kolom yang diminta Bu Rina:
📄 Berkas database/migrations/xxxx_create_siswas_table.php — ganti isi method up()
Membaca kodenya:
| Baris | Arti |
|---|---|
$table->id() |
Kolom id angka otomatis naik, kunci utama tiap siswa. |
$table->string('nama') |
Kolom teks pendek untuk nama. |
$table->string('program_les') |
Kolom teks untuk program les. |
$table->string('no_hp') |
Kolom teks untuk nomor HP. Perhatikan: teks, bukan angka. Alasannya kamu buktikan sendiri di Bab 9. |
$table->timestamps() |
Dua kolom otomatis: created_at dan updated_at. |
Jalankan migration:
Laravel akan menjalankan migration yang belum pernah dijalankan. Kalau muncul pertanyaan bahwa berkas database belum ada dan apakah akan dibuatkan, jawab yes. Periksa hasilnya:
Migration create_siswas_table harus berstatus Ran.
2.4Langkah 3 — Isi model
Buka app/Models/Siswa.php dan tambahkan $fillable:
📄 Ganti seluruh isi berkas app/Models/Siswa.php
2.5Uji coba lewat tinker
tinker adalah ruang percobaan: kamu mengetik kode PHP dan langsung melihat hasilnya.
Ketik baris demi baris (tanda > adalah prompt tinker, jangan diketik):
Hasil Siswa::all() harus menampilkan data Budi. Keluar dari tinker dengan exit.
💥 Galat yang sengaja dibuat: lupa $fillable
- Di
Siswa.php, beri komentar//di depan barisprotected $fillable ..., lalu simpan. - Buka
php artisan tinkerlagi (tutup dulu yang lama denganexitsupaya kode terbaru terbaca). - Ulangi
Siswa::create([...])dengan data lain.
Kamu akan melihat galat MassAssignmentException. Tulis di bukumu: apa bunyi galatnya, dan apa artinya menurutmu? Kembalikan barisnya setelah selesai.
2.6Jalankan test
Empat test memeriksa: tabel punya kolom yang diminta, create() menyimpan data, nomor HP yang diawali nol tetap utuh sebagai teks, dan kolom di luar $fillable (mis. id) tidak bisa diisi massal.
Harapannya: Tests: 4 passed. Angka assertions di sebelahnya boleh berbeda.
Titik periksa Bab 2
Centang setiap butir yang sudah kamu selesaikan.
- Tiga berkas (model, migration, controller) sudah terbentuk dan aku tahu lokasinya.
php artisan migrate:status→ migrationcreate_siswas_tableberstatus Ran.Siswa::all()di tinker menampilkan data Budi.- Tanpa
$fillable,create()gagal denganMassAssignmentException, dan setelah dikembalikan, berhasil lagi. php artisan test --filter=ModelSiswaTest→ 4 test hijau.
Pertanyaan pemahaman
- Apa fungsi migration? Apa bedanya dengan membuat tabel lewat phpMyAdmin?
- Laravel menebak nama tabel dari nama model. Tabel apa yang dipakai model
Siswa? Bagaimana kamu membuktikannya? - Apa fungsi
$fillable? Apa yang terjadi kalau dikosongkan? - Mengapa
no_hpbertipestring, bukaninteger? Tulis dugaanmu sekarang, lalu buktikan di Bab 9.
Tantangan
Tambahkan kolom baru kelas (teks, boleh kosong) ke tabel. Langkahnya: ubah migration ($table->string('kelas')->nullable();), tambahkan 'kelas' ke $fillable, lalu jalankan php artisan migrate:fresh. Perhatikan apa yang terjadi pada data Budi, dan kenapa. Setelah selesai, kembalikan perubahan itu agar test tetap hijau.
Kesalahan umum
| Gejala | Penyebab & solusi |
|---|---|
Class "App\Models\Siswa" not found |
Model belum dibuat, atau use App\Models\Siswa; belum ditulis di tinker. |
SQLSTATE: no such table: siswas |
php artisan migrate belum dijalankan. |
MassAssignmentException |
$fillable kosong atau salah ketik nama kolom. |
| Migration sudah dijalankan tetapi kolom baru tidak ada | Migration lama tidak dijalankan ulang. Saat belajar, pakai php artisan migrate:fresh (menghapus semua data lalu membuat ulang). |
Table 'siswas' already exists |
Migration dijalankan dua kali lewat cara lain. Jalankan php artisan migrate:fresh. |
Test merah: Schema::hasColumns gagal |
Nama kolom di migration salah ketik. Cocokkan dengan tabel di 2.3. |
➡️ Lanjut ke Bab 3 — Data Awal dengan Seeder.