Pendahuluan — menghubungkan kartu anggota ke slip pinjam
Artikel ini adalah #64 (ini) di Seri 5: Laravel Lanjutan. Setelah jalur Laravel dari nol selesai di CRUD API Buku: Ubah & Hapus (#63), sekarang kita masuk ke lapisan yang lebih nyata: hubungan antar data.
Di dunia perpustakaan, buku tidak berdiri sendirian. Ada anggota yang meminjam, ada buku yang dipinjam, dan ada catatan peminjaman yang menjadi penghubung keduanya. Di Laravel, hubungan seperti ini disebut relasi Eloquent. Nanti hasil gabungan ini dibaca oleh pemanggil, yaitu aplikasi atau alat yang memanggil API.
Awam: bayangkan tiga kartu. Kartu pertama = data anggota. Kartu kedua = data buku. Kartu ketiga = slip pinjam yang menuliskan “siapa meminjam buku apa”. Slip itu menunjuk ke dua kartu lain. Hari ini kita belajar cara menulis hubungan itu dengan rapi.
Prasyarat: sudah selesai CRUD API Buku: Ubah & Hapus (#63), paham Auth API Dasar: Login & Kartu Anggota (#61), dan fondasi Instal PHP, Composer & Proyek Laravel (#56) / Struktur Folder,
.env& Artisan Laravel (#57). Pakai Laravel 13+ — butuh PHP 8.3+.
Spesifikasi fitur — apa yang selesai hari ini?
Tiga hal ini yang kita kejar:
- Buat model relasi —
Anggota,Buku, danPeminjamansaling terhubung. - Bisa membaca data gabungan — satu catatan pinjam bisa menampilkan nama anggota dan judul buku sekaligus.
- Punya fondasi untuk artikel berikutnya — daftar panjang pinjam, policy, resource, dan test semua bergantung pada relasi ini.
Awam: selesai artikel ini, kamu belum sedang membangun loket “izin” atau “JSON rapi”. Kamu sedang memasang peta jalan supaya Laravel tahu buku mana milik slip pinjam yang mana, anggota mana yang terlibat, dan jawaban apa yang harus dibaca oleh pemanggil API nanti.
Istilah — ringkas untuk relasi
| Istilah | Arti awam | Catatan |
|---|---|---|
| Relasi | Hubungan antar data | Siapa terhubung ke siapa |
belongsTo |
Baris ini “milik” satu baris lain | Satu slip pinjam milik satu buku, dan milik satu anggota |
hasMany |
Satu baris punya banyak pasangan | Satu anggota punya banyak slip pinjam |
buku_id |
Nomor buku yang ditunjuk slip | Kunci penghubung ke tabel buku |
anggota_id |
Nomor anggota yang meminjam | Kunci penghubung ke tabel anggota |
Urutan belajar kita: array PHP dulu -> lihat relasi secara kasat mata -> baru bungkus dengan hasMany dan belongsTo di Eloquent.
Persiapan — alat yang kamu buka
Alat yang dipakai di artikel ini (fondasi dari Instal PHP, Composer & Proyek Laravel (#56) dan Struktur Folder, .env & Artisan Laravel (#57) — tidak ada unduhan Composer baru hari ini):
- Explorer — cek folder proyek
perpustakaan-api, lalu lihat lokasiapp\Modelsdan folderdatabase\migrations. - Terminal — Laragon: menu Terminal · XAMPP: tombol Shell. Hindari CMD/PowerShell dari Start Menu kalau PATH PHP-mu belum rapi.
- Editor teks — Notepad / VS Code — untuk membuka model hasil
make:model. Contoh paling aman:notepad app\Models\Anggota.phplalunotepad app\Models\Peminjaman.php. - Browser — opsional saja. Hari ini inti uji ada di terminal dan file contoh PHP, bukan di address bar browser.
Awam: untuk artikel ini satu terminal sebenarnya cukup. Tapi kalau kamu mau menjaga php artisan serve dari artikel sebelumnya tetap hidup, pakai terminal kedua untuk menjalankan demo PHP dan perintah Artisan di bawah.
Buka terminal Laragon/Shell XAMPP, masuk ke folder proyek:
cd C:\laragon\www\perpustakaan-api
Di XAMPP biasanya: cd C:\xampp\htdocs\perpustakaan-api. Sesuaikan kalau foldermu beda.
Install-dari-nol: kalau php atau composer belum dikenali terminal, kembali dulu ke Instal PHP, Composer & Proyek Laravel (#56). Kalau struktur folder proyek masih membingungkan, ulangi Struktur Folder, .env & Artisan Laravel (#57).
Kenapa PHP biasa dulu?
Kalau langsung loncat ke tiga model Eloquent, pemula sering cuma menghafal fungsi tanpa benar-benar paham hubungan datanya. Maka kita mulai dari array: lihat buku, lihat anggota, lihat slip pinjam, lalu cocokkan nomornya.
<?php
$buku = [
["id" => 1, "judul" => "Dasar PHP"],
["id" => 2, "judul" => "Belajar Laravel"],
];
$anggota = [
["id" => 10, "nama" => "Budi"],
["id" => 11, "nama" => "Siti"],
];
$peminjaman = [
["id" => 100, "buku_id" => 1, "anggota_id" => 10, "status" => "aktif"],
];
Awam: di sini relasi belum memakai Laravel sama sekali. Tapi hubungan itu sudah ada: slip pinjam 100 menunjuk buku 1 dan anggota 10. Laravel nanti hanya membantu membacanya lebih rapi.
Gabungkan data dengan PHP dulu
<?php
$buku = [
1 => ["id" => 1, "judul" => "Dasar PHP"],
2 => ["id" => 2, "judul" => "Belajar Laravel"],
];
$anggota = [
10 => ["id" => 10, "nama" => "Budi"],
11 => ["id" => 11, "nama" => "Siti"],
];
$peminjaman = ["id" => 100, "buku_id" => 1, "anggota_id" => 10, "status" => "aktif"];
$hasil = [
"id" => $peminjaman["id"],
"judul_buku" => $buku[$peminjaman["buku_id"]]["judul"],
"nama_anggota" => $anggota[$peminjaman["anggota_id"]]["nama"],
"status" => $peminjaman["status"],
];
echo json_encode($hasil, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), PHP_EOL;
Kalau dijalankan, kamu mendapat satu baris gabungan yang enak dibaca: judul buku + nama anggota + status. Itulah rasa dasar relasi: data diambil dari tempat lain lewat nomor penghubung.
Awam — cara menguji bagian ini: potongan pertama dan kedua di atas boleh kamu salin ke satu file misalnya relasi-dasar.php, lalu jalankan di terminal: php relasi-dasar.php. Kalau terminal menjawab JSON berisi judul_buku dan nama_anggota, berarti sintaks dasarmu sudah sehat sebelum menyentuh Laravel.
Masuk ke Laravel — model apa saja?
Di proyek Laravel, kita akan punya tiga model inti:
Buku— data bukuAnggota— data peminjamPeminjaman— baris penghubung buku + anggota
Awam: model itu bukan mantra. Anggap saja seperti tiga map data yang beda. Kita sedang mengajari tiap map cara saling kenal, supaya pengatur kode (controller) nanti bisa membaca data gabungan tanpa menyambung manual terus-menerus.
php artisan make:model Anggota -m
php artisan make:model Peminjaman -m
Setelah perintah itu jalan, Laravel akan membuat file model dan file migration. Buka modelnya dengan editor:
notepad app\Models\Anggota.php
notepad app\Models\Peminjaman.php
Awam: kalau kamu melihat pesan “Could not open input file” atau “php tidak dikenal”, itu masalah terminal/PATH, bukan relasi. Kembali ke artikel instalasi dulu; jangan memaksa lanjut sambil error dasarnya belum beres.
Cuplikan relasi di model Laravel
<?php
// app/Models/Anggota.php
use Illuminate\Database\Eloquent\Relations\HasMany;
public function peminjaman(): HasMany
{
return $this->hasMany(Peminjaman::class);
}
<?php
// app/Models/Peminjaman.php
use Illuminate\Database\Eloquent\Relations\BelongsTo;
public function buku(): BelongsTo
{
return $this->belongsTo(Buku::class);
}
public function anggota(): BelongsTo
{
return $this->belongsTo(Anggota::class);
}
Awam: kalimatnya dibaca begini:
- Anggota hasMany Peminjaman = satu anggota bisa punya banyak slip pinjam
- Peminjaman belongsTo Buku = satu slip menunjuk satu buku
- Peminjaman belongsTo Anggota = satu slip menunjuk satu anggota
Membaca data gabungan lewat Eloquent
<?php
$rows = Peminjaman::with(['buku', 'anggota'])->get();
foreach ($rows as $row) {
echo $row->anggota->nama.' meminjam '.$row->buku->judul.PHP_EOL;
}
Awam: with(['buku', 'anggota']) berarti: “saat ambil slip pinjam, sekalian bawa buku dan anggota yang terhubung”. Jadi saat mencetak, pemanggil atau pengatur kode tidak pusing memburu nomor satu per satu lagi.
Pola Dasar — membaca relasi dengan nyaman
-
1
Tentukan map data
Buku, anggota, dan peminjaman punya tempat masing-masing. -
2
Pasang nomor penghubung
buku_iddananggota_idhidup di slip peminjaman. -
3
Lihat dengan array dulu
Supaya hubungan datanya terlihat jelas, bukan sekadar hafalan fungsi. -
4
Tuliskan relasi
hasManydi pemilik banyak,belongsTodi penunjuk. -
5
Ambil data gabungan
Pakaiwith()agar buku dan anggota ikut terbaca. -
6
Siapkan artikel berikutnya
Setelah relasi benar, pagination jadi jauh lebih masuk akal.
Kode lengkap — demo mandiri relasi sederhana
Simpan sebagai laravel_eloquent_relasi_peminjaman_demo.php, lalu jalankan php laravel_eloquent_relasi_peminjaman_demo.php:
<?php
declare(strict_types=1);
$buku = [
1 => ["id" => 1, "judul" => "Dasar PHP"],
2 => ["id" => 2, "judul" => "Belajar Laravel"],
];
$anggota = [
10 => ["id" => 10, "nama" => "Budi"],
11 => ["id" => 11, "nama" => "Siti"],
];
$peminjaman = [
["id" => 100, "buku_id" => 1, "anggota_id" => 10, "status" => "aktif"],
["id" => 101, "buku_id" => 2, "anggota_id" => 11, "status" => "kembali"],
];
function gabungRelasi(array $row, array $buku, array $anggota): array
{
return [
"id" => $row["id"],
"judul_buku" => $buku[$row["buku_id"]]["judul"],
"nama_anggota" => $anggota[$row["anggota_id"]]["nama"],
"status" => $row["status"],
];
}
function demo(string $judul, callable $aksi): void
{
echo "=== {$judul} ===", PHP_EOL;
echo json_encode($aksi(), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), PHP_EOL, PHP_EOL;
}
demo("Satu slip gabungan", function () use ($peminjaman, $buku, $anggota) {
return gabungRelasi($peminjaman[0], $buku, $anggota);
});
demo("Dua slip gabungan", function () use ($peminjaman, $buku, $anggota) {
return array_map(fn ($row) => gabungRelasi($row, $buku, $anggota), $peminjaman);
});
Awam: demo(...) hanya pembungkus output. declare(strict_types=1); artinya PHP lebih ketat membaca tipe data; boleh diikuti, tidak wajib dihafal. Yang penting adalah fungsi gabungRelasi: dia mengambil satu slip, lalu mencari buku dan anggota yang cocok berdasarkan nomor.
Kesalahan umum
| Gejala | Penyebab tipikal | Perbaikan awam |
|---|---|---|
| Nama anggota kosong | anggota_id salah atau model belum terhubung |
Cek nomor penghubung dan relasi belongsTo |
| Judul buku tidak muncul | buku_id tidak cocok dengan data buku |
Pastikan slip menunjuk buku yang benar |
| Data gabungan lambat atau berulang | Ambil relasi satu per satu tanpa strategi | Belajar with() dan daftar gabungan dengan rapi |
| Relasi terasa abstrak | Langsung hafal fungsi tanpa melihat contoh data | Kembali ke array PHP dulu sampai hubungan datanya terasa |
Latihan singkat
- Tambahkan satu anggota baru dan satu slip pinjam baru ke demo, lalu cek apakah hasil gabungan ikut muncul.
- Jelaskan ke teman: kenapa
peminjamanlebih cocok menjadi tabel penghubung daripada menaruh semua informasi di tabel buku. - Tulis satu kalimat: beda
hasManydanbelongsTodengan bahasa awam.
FAQ singkat
Kenapa tidak langsung policy atau resource?
Karena policy, resource, dan pagination baru terasa berguna kalau hubungan datanya sudah benar. Artikel ini memasang fondasi itu.
Apakah satu buku bisa dipinjam berkali-kali?
Secara konsep iya. Itulah kenapa satu buku bisa muncul di banyak baris peminjaman pada waktu yang berbeda.
Tool apa yang dibuka dulu?
Mulai dari Explorer untuk memastikan folder proyek benar, lalu satu terminal di folder proyek, lalu editor. Browser opsional saja hari ini. Kalau serve dari artikel sebelumnya masih dibiarkan hidup, pakai terminal kedua untuk demo PHP dan perintah Artisan.
Potongan sintaks diuji di mana?
Potongan PHP biasa diuji di terminal dengan php nama-file.php. Potongan Laravel ditempel ke file model seperti app\Models\Anggota.php dan app\Models\Peminjaman.php.
Ke mana setelah ini?
Berikutnya alami: Pagination, Filter & Pencarian (#65) untuk daftar slip pinjam yang makin panjang.
Kesimpulan
Kamu sudah belajar fondasi relasi: anggota, buku, dan peminjaman saling terhubung. Mulai dari array PHP dulu, lalu pindah ke hasMany dan belongsTo di Laravel. Setelah ini, lanjut ke Pagination, Filter & Pencarian (#65) supaya daftar pinjam panjang terasa rapi dan mudah diolah.
Seri 5 progress: langkah #64 (ini) · 1/7 Laravel Lanjutan · prasyarat: CRUD API Buku: Ubah & Hapus (#63) LIVE. Berikutnya: Pagination, Filter & Pencarian (#65).