Pada pertemuan ini, kita akan membangun sebuah sistem akademik sederhana dengan beberapa relasi antar entitas, yaitu:
- Setiap mahasiswa (Student) terhubung ke satu jurusan (Major) (relasi Many-to-One).
- Mahasiswa dapat mengambil banyak mata kuliah (Subject) melalui tabel pivot (relasi Many-to-Many).
- Setiap jurusan (Major) memiliki banyak mahasiswa (relasi One-to-Many).
- Sebuah mata kuliah (Subject) dapat diikuti oleh banyak mahasiswa melalui tabel pivot (relasi Many-to-Many).
Untuk lebih jelasnya, berikut adalah Entity Relationship Diagram (ERD) dari database yang akan kita terapkan dalam proyek ini.


Pada pertemuan kali ini, kita akan memulai dengan membuat project baru karena kita akan menggunakan database yang berbeda dari sebelumnya. Untuk memudahkan, kita cukup menggunakan SQLite sebagai database-nya.
Setelah project Laravel baru berhasil dibuat secara lokal, langkah pertama yang perlu dilakukan adalah membuat migrasi database.
A. Migrasi untuk tabel majors
Untuk membuat migrasi tabel majors, jalankan perintah berikut di terminal:
php artisan make:migration create_majors_table
Kemudian tambahkan kode berikut pada function up():
Schema::create('majors', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
B. Migration untuk tabel students
Buat migrasi database dengan perintah berikut:
bashCopyEditphp artisan make:migration create_students_table
Kemudian tambahkan kode berikut pada function up():
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 untuk tabel subjects
Buat migrasi database dengan perintah berikut:
php artisan make:migration create_subjects_table
Kemudian tambahkan kode berikut pada function up():
Schema::create('subjects', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('sks');
$table->timestamps();
});
D. Migration untuk tabel pivot student_subject
Buat migrasi database dengan perintah berikut:
bashCopyEditphp artisan make:migration create_student_subject_table
Kemudian tambahkan kode berikut pada function up():
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();
// Mencegah duplikasi kombinasi student_id dan subject_id
$table->unique(['student_id', 'subject_id']);
});
Setelah seluruh file migrasi selesai dibuat dan disimpan, jalankan proses migrasi dengan perintah:
php artisan migrate
jika berhasil,maka hasilnya akan seperti ini :

Langkah selanjutnya yaitu membuat model dengan relasi sesuai dengan struktur database yang telah dibuat melalui migrasi sebelumnya.
A. Model Major
Buat model dengan perintah:
php artisan make:model Major
Isi file model Major.php dengan kode berikut:
<?php
// app/Models/Major.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Major extends Model
{
use HasFactory;
protected $fillable = ['name'];
// Relasi: Satu jurusan memiliki banyak mahasiswa
public function students()
{
return $this->hasMany(Student::class);
}
}
B. Model Student
Buat model dengan perintah:
bashCopyEditphp artisan make:model Student
Isi file model Student.php dengan kode berikut:
<?php
// app/Models/Student.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
use HasFactory;
protected $fillable = ['nim', 'name', 'address', 'major_id'];
// Relasi: Mahasiswa milik satu jurusan
public function major()
{
return $this->belongsTo(Major::class);
}
// Relasi: Mahasiswa mengambil banyak mata kuliah
public function subjects()
{
return $this->belongsToMany(Subject::class);
}
}
C. Model Subject
Buat model dengan perintah:
php artisan make:model Subject
Isi file model Subject.php dengan kode berikut:
<?php
// app/Models/Subject.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Subject extends Model
{
use HasFactory;
protected $fillable = ['name', 'sks'];
// Relasi: Mata kuliah diambil oleh banyak mahasiswa
public function students()
{
return $this->belongsToMany(Student::class);
}
}
Langkah berikutnya adalah membuat seeder untuk mengisi data ke dalam database.
A. Seeder untuk Major
Buat seeder dengan perintah:
php artisan make:seeder MajorSeeder
Isi file MajorSeeder.php dengan kode berikut:
<?php
// database/seeders/MajorSeeder.php
namespace Database\Seeders;
use App\Models\Major;
use Illuminate\Database\Seeder;
class MajorSeeder extends Seeder
{
public function run()
{
$majors = [
['name' => 'Teknik Informatika'],
['name' => 'Sistem Informasi'],
['name' => 'Teknik Komputer'],
['name' => 'Manajemen Informatika'],
];
foreach ($majors as $major) {
Major::create($major);
}
}
}
B. Seeder untuk Subject
Buat seeder dengan perintah:
php artisan make:seeder SubjectSeeder
Isi file SubjectSeeder.php dengan kode berikut:
<?php
// database/seeders/SubjectSeeder.php
namespace Database\Seeders;
use App\Models\Subject;
use Illuminate\Database\Seeder;
class SubjectSeeder extends Seeder
{
public function run()
{
$subjects = [
['name' => 'Pemrograman Web', 'sks' => 3],
['name' => 'Database', 'sks' => 3],
['name' => 'Algoritma', 'sks' => 2],
['name' => 'Jaringan Komputer', 'sks' => 3],
['name' => 'Sistem Operasi', 'sks' => 2],
];
foreach ($subjects as $subject) {
Subject::create($subject);
}
}
}
C. Seeder untuk Student
Buat seeder dengan perintah:
php artisan make:seeder StudentSeeder
Isi file StudentSeeder.php dengan kode berikut:
<?php
// database/seeders/StudentSeeder.php
namespace Database\Seeders;
use App\Models\Student;
use App\Models\Subject;
use Illuminate\Database\Seeder;
class StudentSeeder extends Seeder
{
public function run()
{
$students = [
['nim' => '20210001', 'name' => 'Ahmad Rizki', 'address' => 'Jl. Merdeka No. 1', 'major_id' => 1],
['nim' => '20210002', 'name' => 'Siti Nurhaliza', 'address' => 'Jl. Sudirman No. 15', 'major_id' => 1],
['nim' => '20210003', 'name' => 'Budi Santoso', 'address' => 'Jl. Pahlawan No. 8', 'major_id' => 2],
['nim' => '20210004', 'name' => 'Dewi Kartika', 'address' => 'Jl. Diponegoro No. 22', 'major_id' => 2],
['nim' => '20210005', 'name' => 'Eko Prasetyo', 'address' => 'Jl. Gatot Subroto No. 11', 'major_id' => 3],
];
foreach ($students as $studentData) {
$student = Student::create($studentData);
// Menetapkan mata kuliah secara acak untuk setiap mahasiswa
$subjects = Subject::inRandomOrder()->take(rand(2, 4))->pluck('id');
$student->subjects()->attach($subjects);
}
}
}
D. Update DatabaseSeeder
Buka file DatabaseSeeder.php dan ubah isi method run() seperti berikut:
<?php
// database/seeders/DatabaseSeeder.php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call([
MajorSeeder::class,
SubjectSeeder::class,
StudentSeeder::class,
]);
}
}
Setelah semua file seeder dibuat dan disimpan, jalankan perintah berikut di terminal untuk menjalankan seeder:
bashCopyEditphp artisan db:seed
Jika berhasil, maka data jurusan, mata kuliah, dan mahasiswa akan otomatis terisi ke dalam database seperti berikut

Langkah selanjutnya yaitu membuat controller untuk masing-masing model.
A. StudentController
Buat controller dengan perintah:
php artisan make:controller StudentControllerKemudian tambahkan kode berikut ke dalam file app/Http/Controllers/StudentController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Student;
use App\Models\Major;
use App\Models\Subject;
use Illuminate\Http\Request;
class StudentController extends Controller
{
public function index()
{
$students = Student::with(['major', 'subjects'])->get();
return view('students.index', compact('students'));
}
public function show($id)
{
$student = Student::with(['major', 'subjects'])->findOrFail($id);
return view('students.show', compact('student'));
}
public function create()
{
$majors = Major::all();
$subjects = Subject::all();
return view('students.create', compact('majors', 'subjects'));
}
public function store(Request $request)
{
$request->validate([
'nim' => 'required|unique:students',
'name' => 'required',
'address' => 'required',
'major_id' => 'required|exists:majors,id',
'subjects' => 'required|array',
'subjects.*' => 'exists:subjects,id',
]);
$student = Student::create($request->only(['nim', 'name', 'address', 'major_id']));
$student->subjects()->attach($request->subjects);
return redirect()->route('students.index')->with('success', 'Student created successfully');
}
public function edit($id)
{
$student = Student::with('subjects')->findOrFail($id);
$majors = Major::all();
$subjects = Subject::all();
return view('students.edit', compact('student', 'majors', 'subjects'));
}
public function update(Request $request, $id)
{
$student = Student::findOrFail($id);
$request->validate([
'nim' => 'required|unique:students,nim,' . $student->id,
'name' => 'required',
'address' => 'required',
'major_id' => 'required|exists:majors,id',
'subjects' => 'required|array',
'subjects.*' => 'exists:subjects,id',
]);
$student->update($request->only(['nim', 'name', 'address', 'major_id']));
$student->subjects()->sync($request->subjects);
return redirect()->route('students.index')->with('success', 'Student updated successfully');
}
public function destroy($id)
{
$student = Student::findOrFail($id);
$student->subjects()->detach();
$student->delete();
return redirect()->route('students.index')->with('success', 'Student deleted successfully');
}
}
Langkah berikutnya adalah membuat routing pada file routes/web.php:
<?php
use App\Http\Controllers\StudentController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return redirect()->route('students.index');
});
Route::resource('students', StudentController::class);
Kemudian buat tampilan (view) di dalam folder resources/views/students.
A. Layout Utama (resources/views/layouts/app.blade.php)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Student Management System</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="{{ route('students.index') }}">Student Management</a>
</div>
</nav>
<div class="container mt-4">
@if(session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
@yield('content')
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
B. Tampilan Index Mahasiswa (resources/views/students/index.blade.php)
@extends('layouts.app')
@section('content')
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Daftar Mahasiswa</h2>
<a href="{{ route('students.create') }}" class="btn btn-primary">Tambah Mahasiswa</a>
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>NIM</th>
<th>Nama</th>
<th>Jurusan</th>
<th>Mata Kuliah</th>
<th>Total SKS</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@foreach($students as $student)
<tr>
<td>{{ $student->nim }}</td>
<td>{{ $student->name }}</td>
<td>{{ $student->major->name }}</td>
<td>
@foreach($student->subjects as $subject)
<span class="badge bg-secondary me-1">{{ $subject->name }}</span>
@endforeach
</td>
<td>{{ $student->subjects->sum('sks') }}</td>
<td>
<a href="{{ route('students.show', $student->id) }}" class="btn btn-info btn-sm">Detail</a>
<a href="{{ route('students.edit', $student->id) }}" class="btn btn-warning btn-sm">Edit</a>
<form action="{{ route('students.destroy', $student->id) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Yakin ingin menghapus?')">Hapus</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection
C. Tampilan Create Mahasiswa (resources/views/students/create.blade.php)
@extends('layouts.app')
@section('content')
<h2>Tambah Mahasiswa</h2>
<div class="card">
<div class="card-body">
<form action="{{ route('students.store') }}" method="POST">
@csrf
<div class="mb-3">
<label for="nim" class="form-label">NIM</label>
<input type="text" class="form-control @error('nim') is-invalid @enderror" id="nim" name="nim" value="{{ old('nim') }}">
@error('nim')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="name" class="form-label">Nama</label>
<input type="text" class="form-control @error('name') is-invalid @enderror" id="name" name="name" value="{{ old('name') }}">
@error('name')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="address" class="form-label">Alamat</label>
<input type="text" class="form-control @error('address') is-invalid @enderror" id="address" name="address" value="{{ old('address') }}">
@error('address')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="major_id" class="form-label">Jurusan</label>
<select name="major_id" id="major_id" class="form-control @error('major_id') is-invalid @enderror">
<option value="">Pilih Jurusan</option>
@foreach ($majors as $major)
<option value="{{ $major->id }}" {{ old('major_id') == $major->id ? 'selected' : '' }}>
{{ $major->name }}
</option>
@endforeach
</select>
@error('major_id')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label class="form-label">Mata Kuliah</label>
@error('subjects')
<div class="text-danger">{{ $message }}</div>
@enderror
@foreach ($subjects as $subject)
<div class="form-check">
<input type="checkbox" class="form-check-input" name="subjects[]" value="{{ $subject->id }}" id="subject{{ $subject->id }}" {{ in_array($subject->id, old('subjects', [])) ? 'checked' : '' }}>
<label for="subject{{ $subject->id }}" class="form-check-label">
{{ $subject->name }} ({{ $subject->sks }} SKS)
</label>
</div>
@endforeach
</div>
<button type="submit" class="btn btn-primary">Simpan</button>
<a href="{{ route('students.index') }}" class="btn btn-secondary">Kembali</a>
</form>
</div>
</div>
@endsection
Jika sudah, maka halaman akan menampilkan form input mahasiswa dan daftar data yang sudah dimasukkan seperti gambar berikut
ini indexnya :

ini create :

TUGAS
1.Query untuk menampilkan Jurusan yang memiliki mahasiswa terbanyak
Pertama, kita ubah terlebih dahulu di StudentController. Tambah kode berikut di method index():
$mostFrequentMajor = Major::withCount('students') // Count students for each major
->orderByDesc('students_count') // Order by the count descending
->first();
Query ini berfungsi untuk mencari dan mengambil satu data jurusan (Major) yang memiliki jumlah mahasiswa terbanyak. Langkah pertamanya (Major::withCount('students')) adalah mengambil semua data jurusan sambil menghitung jumlah mahasiswa yang berelasi dengan setiap jurusan. Hasil hitungan ini disimpan dalam kolom virtual bernama students_count. Kemudian (orderByDesc('students_count')) hasilnya diurutkan secara menurun berdasarkan jumlah mahasiswa tersebut. Terakhir (first()) diambil satu record pertama dari hasil pengurutan, yang secara efektif adalah jurusan dengan jumlah mahasiswa terbanyak.
Kemudian pada index (resources/views/students/index.blade.php) di bawah tabel tambahkan kode berikut:
@if ($mostFrequentMajor)
<div class="alert alert-info mt-4" role="alert">
Jurusan yang paling banyak dipilih mahasiswa adalah: <strong>{{ $mostFrequentMajor->name }}</strong> (dengan {{ $mostFrequentMajor->students_count }} mahasiswa).
</div>
@endif
Hasilnya akan menampilkan informasi tambahan di bawah tabel berupa nama jurusan dengan jumlah mahasiswa terbanyak seperti berikut

- Menambahkan View Detail menggunakan controller
show()
Kode viewnya adalah sebagai berikut. Buat file resources/views/students/show.blade.php dan isi dengan:
@extends('layouts.app')
@section('content')
<h2>Detail Mahasiswa</h2>
<div class="card">
<div class="card-body">
<div class="mb-3">
<label for="nim" class="form-label">NIM:</label>
<p id="nim">{{ $student->nim }}</p>
</div>
<div class="mb-3">
<label for="name" class="form-label">Nama:</label>
<p id="name">{{ $student->name }}</p>
</div>
<div class="mb-3">
<label for="address" class="form-label">Alamat:</label>
<p id="address">{{ $student->address }}</p>
</div>
<div class="mb-3">
<label for="major" class="form-label">Jurusan:</label>
<p id="major">{{ $student->major->name }}</p>
</div>
<div class="mb-3">
<label class="form-label">Mata Kuliah Diambil:</label>
@if ($student->subjects->count() > 0)
<ul>
@foreach ($student->subjects as $subject)
<li>{{ $subject->name }} ({{ $subject->sks }} SKS)</li>
@endforeach
</ul>
<p><strong>Total SKS:</strong> {{ $student->subjects->sum('sks') }}</p>
@else
<p>Tidak ada mata kuliah yang diambil.</p>
@endif
</div>
<a href="{{ route('students.index') }}" class="btn btn-secondary">Kembali ke Daftar</a>
</div>
</div>
@endsection
View ini akan menampilkan informasi lengkap tentang satu mahasiswa, termasuk NIM, nama, alamat, jurusan, daftar mata kuliah yang diambil beserta jumlah SKS, serta tombol kembali ke halaman daftar mahasiswa.

- Menambahkan view edit dari controller
update()
Buat file resources/views/students/edit.blade.php dengan kode berikut:
@extends('layouts.app')
@section('content')
<h2>Edit Mahasiswa</h2>
<div class="card">
<div class="card-body">
<form action="{{ route('students.update', $student->id) }}" method="POST">
@csrf
@method('PUT') {{-- Gunakan metode PUT untuk update --}}
<div class="mb-3">
<label for="nim" class="form-label">NIM</label>
{{-- Isi dengan data lama mahasiswa atau data inputan jika validasi gagal --}}
<input type="text" class="form-control @error('nim') is-invalid @enderror"
id="nim" name="nim" value="{{ old('nim', $student->nim) }}">
@error('nim')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="name" class="form-label">Nama</label>
<input type="text" class="form-control @error('name') is-invalid @enderror"
id="name" name="name" value="{{ old('name', $student->name) }}">
@error('name')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="address" class="form-label">Alamat</label>
<input type="text" class="form-control @error('address') is-invalid @enderror"
id="address" name="address" value="{{ old('address', $student->address) }}">
@error('address')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="major_id" class="form-label">Jurusan</label>
<select name="major_id" id="major_id" class="form-control @error('major_id') is-invalid @enderror" >
<option value="">Pilih Jurusan</option>
@foreach ($majors as $major)
{{-- Pilih jurusan yang sudah terpilih sebelumnya --}}
<option value="{{ $major->id }}" {{ old('major_id', $student->major_id) == $major->id ? 'selected' : '' }}>
{{ $major->name }}
</option>
@endforeach
</select>
@error('major_id')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label class="form-label">Mata Kuliah</label>
@error('subjects')
<div class="text-danger">{{ $message }}</div>
@enderror
@foreach ($subjects as $subject)
<div class="form-check">
<input type="checkbox" class="form-check-input" name="subjects[]"
value="{{ $subject->id }}" id="subject{{ $subject->id }}"
{{-- Cek apakah mata kuliah sudah dipilih --}}
{{ in_array($subject->id, old('subjects', $student->subjects->pluck('id')->toArray())) ? 'checked' : '' }}>
<label for="subject{{ $subject->id }}" class="form-check-label">
{{ $subject->name }} ({{ $subject->sks }} SKS)
</label>
</div>
@endforeach
</div>
<button type="submit" class="btn btn-primary">Update</button>
<a href="{{ route('students.index') }}" class="btn btn-secondary">Batal</a>
</form>
</div>
</div>
@endsection
Tampilan ini memungkinkan pengguna untuk mengedit data mahasiswa, mengubah jurusan, dan memilih atau menghapus mata kuliah yang diambil. Ada validasi dan feedback error pada setiap input jika ada kesalahan.

KESIMPULAN
Dalam proyek sistem akademik sederhana ini, kita telah membuat struktur database menggunakan migrasi Laravel untuk tabel majors, students, subjects, dan tabel pivot student_subject guna mengatur relasi Many-to-Many antara mahasiswa dan mata kuliah. Model Eloquent dibuat sesuai dengan relasi yang diinginkan, yaitu Major-One to Many-Student dan Student-Many to Many-Subject.
Selanjutnya, data awal dimasukkan ke database menggunakan seeder untuk tabel jurusan, mata kuliah, dan mahasiswa beserta mata kuliah yang diambil secara acak.
Controller StudentController dibuat untuk mengelola operasi CRUD mahasiswa, dengan fungsi index menampilkan daftar mahasiswa lengkap dengan jurusan dan mata kuliah, serta menampilkan jurusan dengan jumlah mahasiswa terbanyak. Fungsi show digunakan untuk menampilkan detail mahasiswa, sedangkan fungsi create dan edit menyediakan form untuk menambah dan mengubah data mahasiswa.
Route resource Laravel mengatur URL agar sesuai dengan controller, dan tampilan dibuat dengan Blade menggunakan Bootstrap untuk mendukung antarmuka yang responsif dan mudah digunakan.
Dengan demikian, aplikasi ini sudah dapat mengelola data mahasiswa, jurusan, dan mata kuliah secara lengkap, termasuk fitur menampilkan jurusan paling populer dan melakukan pengelolaan data mahasiswa secara interaktif melalui form tambah, edit, lihat detail, dan hapus data.