LARAVEL RELATIONSHIP
Praktikum kali ini berfokus pada penerapan hubungan antar-tabel (Database Relationship) menggunakan ORM (Object-Relational Mapping) bawaan Laravel yaitu Eloquent. Dalam sistem basis data relasional, sebuah entitas sering kali memiliki keterkaitan dengan entitas lainnya. Laravel memudahkan pengelolaan hubungan ini melalui penulisan kode PHP yang ekspresif di dalam berkas Model.
Dalam praktikum ini, terdapat tiga entitas utama yang saling berhubungan:
Jenis relasi yang diterapkan dalam praktikum ini meliputi:
student_subject.Langkah pertama yaitu membuat file migrasi untuk mendefinisikan skema struktur tabel database di terminal menggunakan perintah Artisan CLI berikut secara berurutan:
php artisan make:migration create_majors_table
php artisan make:migration create_students_table
php artisan make:migration create_subjects_table
php artisan make:migration create_student_subject_table
Setelah berkas migrasi berhasil di-generate di dalam direktori database/migrations/, struktur kolom ditambahkan sebagai berikut:
A. Migration Tabel Majors:
Schema::create('majors', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
B. Migration Tabel Students: Kolom major_id diset sebagai foreign key yang terhubung langsung dengan tabel majors menggunakan metode constrained() dengan aksi onDelete('cascade').
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string('nim')->unique();
$table->string('name');
$table->text('address');
$table->foreignId('major_id')->constrained('majors')->onDelete('cascade');
$table->timestamps();
});
C. Migration Tabel Subjects:
Schema::create('subjects', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('sks');
$table->timestamps();
});
D. Migration Tabel Pivot Student_Subject: Menyimpan relasi perantara Many-to-Many dengan penambahan aturan unique(['student_id', 'subject_id']) untuk mencegah satu mahasiswa mendaftarkan satu mata kuliah yang sama secara ganda di KRS.
Schema::create('student_subject', function (Blueprint $table) {
$table->id();
$table->foreignId('student_id')->constrained('students')->onDelete('cascade');
$table->foreignId('subject_id')->constrained('subjects')->onDelete('cascade');
$table->timestamps();
$table->unique(['student_id', 'subject_id']);
});
Setelah seluruh definisi migration selesai disusun, ketikkan perintah berikut untuk bermigrasi secara fisik ke dalam MySQL:
php artisan migrate
Model digunakan untuk merepresentasikan entitas data dan mengonfigurasi logika relasi di Laravel. Kita akan menghasilkan model Major, Student, dan Subject.
A. Model Major (app/Models/Major.php): Mendeklarasikan relasi One-to-Many menggunakan metode hasMany() ke model Student.
class Major extends Model
{
use HasFactory;
protected $fillable = ['name'];
public function students()
{
return $this->hasMany(Student::class);
}
}
B. Model Student (app/Models/Student.php): Mendeklarasikan relasi Many-to-One menggunakan belongsTo() dan relasi Many-to-Many menggunakan belongsToMany().
class Student extends Model
{
use HasFactory;
protected $fillable = ['nim', 'name', 'address', 'major_id'];
public function major()
{
return $this->belongsTo(Major::class);
}
public function subjects()
{
return $this->belongsToMany(Subject::class);
}
}
C. Model Subject (app/Models/Subject.php): Mendefinisikan relasi timbal balik Many-to-Many menggunakan belongsToMany().
class Subject extends Model
{
use HasFactory;
protected $fillable = ['name', 'sks'];
public function students()
{
return $this->belongsToMany(Student::class);
}
}
Seeder digunakan untuk mengotomatisasi pengisian baris data uji awal ke dalam database relasi.
php artisan make:seeder MajorSeeder
php artisan make:seeder SubjectSeeder
php artisan make:seeder StudentSeeder
Pada berkas StudentSeeder.php, setelah data mahasiswa disimpan, kita pasangkan relasi mata kuliah secara acak (random assignment) menggunakan metode attach():
foreach ($students as $studentData) {
$student = Student::create($studentData);
$subjects = Subject::inRandomOrder()->take(rand(2, 4))->pluck('id');
$student->subjects()->attach($subjects);
}
Terakhir, daftarkan seluruh sub-seeder tersebut di dalam DatabaseSeeder.php secara berurutan, lalu jalankan perintah:
php artisan db:seed
Controller memegang peranan penting dalam mengelola logika pemrosesan data relasi akademik. Berkas controller dibuat dengan perintah:
php artisan make:controller StudentController
Berikut penjelasan logika metode CRUD relasi yang diimplementasikan dalam controller:
index(): Menampilkan daftar mahasiswa. Menggunakan metode Eager Loading Student::with(['major', 'subjects']) untuk mengoptimalkan query database dan mencegah masalah N+1 Query.store(): Memvalidasi masukan form, menyimpan data mahasiswa baru, lalu menyisipkan keterikatan mata kuliah yang dipilih ke tabel pivot lewat fungsi attach().update(): Memperbarui profil dasar mahasiswa sekaligus memperbarui relasi mata kuliah pilihan teranyar secara efisien menggunakan metode sync().destroy(): Memutuskan keterikatan relasi mahasiswa di tabel pivot terlebih dahulu dengan fungsi detach() sebelum mengeksekusi penghapusan entitas mahasiswa tersebut.
Rute dideklarasikan di dalam file routes/web.php. Rute resource membantu memetakan URL ke fungsi controller secara instan, ditambah rute khusus untuk melihat evaluasi latihan relasi database:
Visualisasi program dibangun menggunakan teknologi Bootstrap 5 dan Blade layouting. File-file view diletakkan di dalam folder resources/views/students/:
layouts/app.blade.php: Master layout sebagai cetakan navigasi bar atas dan pembatas konten utama halaman web.students/index.blade.php: Menyusun visualisasi tabel mahasiswa, daftar lencana program studi, deretan lencana mata kuliah terdaftar, serta akumulasi total sks.students/create.blade.php & edit.blade.php: Formulir input dinamis yang menampilkan checkbox mata kuliah pilihan menggunakan bantuan perbandingan array in_array().students/show.blade.php: Kartu Rencana Studi (KRS) representatif yang merinci data akademik lengkap dari mahasiswa yang bersangkutan.Tampilan Halaman Utama / KRS Mahasiswa pada Local Server:
Tampilan Halaman tambah mahasiswa
Tampilan Halaman detail mahasiswa
Tampilan Halaman hapus mahasiswa
Soal 1: Menampilkan semua mahasiswa beserta jurusan dan mata kuliahnya (Eager Loading)
Untuk menghemat muatan server, query ditulis menggunakan pemanggilan fungsi with() yang menggabungkan relasi major dan subjects sekaligus.
$students = Student::with(['major', 'subjects'])->get();
Soal 2: Mencari program studi (jurusan) yang memiliki mahasiswa terdaftar terbanyak
Query memanggil database untuk menghitung jumlah relasi menggunakan withCount(), lalu mengurutkannya secara terbalik dan mengambil baris teratas.
$mostPopularMajor = Major::withCount('students')
->orderBy('students_count', 'desc')
->first();
Soal 3: Menemukan daftar mata kuliah yang diambil oleh mahasiswa spesifik
memanggil data record mahasiswa sampel, lalu memanggil relasi dinamis subjects-nya.
$selectedStudent = Student::with('subjects')->first();
$studentSubjects = $selectedStudent ? $selectedStudent->subjects : collect();
Soal 4: Menghitung total SKS yang diambil oleh masing-masing mahasiswa
Penjumlahan bobot SKS diproses secara otomatis langsung di dalam visualisasi Blade menggunakan fungsi agregasi koleksi sum().
$student->subjects->sum('sks')
Tampilan Halaman Query Relationship
Berdasarkan pengerjaan praktikum yang telah diselesaikan, beberapa kesimpulan penting yang dapat diambil adalah:
Student::with(...)) sangat krusial dalam aplikasi nyata untuk memangkas penumpukan query database berlebih (N+1 Query Problem), yang secara signifikan mengoptimalkan performa beban kerja server.attach(), sync(), dan detach().