- Sistem Informasi Perpustakaan CodeIgniter 4: Rancangan Aplikasi SIPUS
- Sistem Informasi Perpustakaan CodeIgniter 4: Setup dan Konfigurasi Database
- Sistem Informasi Perpustakaan CodeIgniter 4: CRUD Kategori Buku
- Membuat Layout Utama SIPUS dengan CodeIgniter 4: Navbar, Sidebar, dan Main Layout
- Membuat CRUD Buku dengan CodeIgniter 4 dan Bootstrap 5 pada Aplikasi SIPUS
MWI – Selamat pagi, halo sobat pembelajar pada website Belajar bersama MUhidin SAimin, kali ini akan melanjutkan pada materi CRUD Buku CodeIgniter 4, mari kita mulai.
Daftar Isi
Pendahuluan
CRUD Buku CodeIgniter 4 merupakan salah satu fitur utama dalam pengembangan aplikasi Sistem Informasi Perpustakaan Sekolah (SIPUS). Melalui tutorial ini, kita akan membangun fitur pengelolaan data buku menggunakan CodeIgniter 4.7.5, PHP, MySQL, dan Bootstrap 5. Selain mempelajari proses tambah, tampil, edit, dan hapus data, kita juga akan memahami validasi form, relasi kategori, serta pengelolaan stok buku.
Fitur CRUD Buku menjadi salah satu bagian utama dalam Sistem Informasi Perpustakaan Sekolah (SIPUS). Melalui fitur ini, admin atau petugas dapat menambahkan, melihat, mengubah, dan menghapus data buku. Selain itu, aplikasi juga menampilkan nama kategori untuk setiap buku.
Pada materi ini, kita menggunakan CodeIgniter 4.7.5, PHP, MySQL, dan Bootstrap 5. Kita juga memanfaatkan Model, Controller, View, validasi form, serta relasi antara tabel books dan categories.
Kita akan mengikuti struktur dan kode yang sudah kita siapkan dalam proyek SIPUS. Dengan demikian, kamu dapat langsung menerapkan setiap langkah tanpa perlu menyesuaikan ulang nama method atau alur program.
Tujuan Pembelajaran CRUD Buku CodeIgniter 4
Setelah mengikuti tutorial ini, kamu akan mampu:
- Memahami struktur tabel buku dan relasinya dengan tabel kategori.
- Membuat Model Buku menggunakan CodeIgniter 4.
- Mengambil data buku beserta nama kategorinya.
- Membuat Controller untuk mengelola data buku.
- Membuat halaman daftar buku menggunakan Bootstrap 5.
- Membuat form tambah dan edit buku.
- Menerapkan validasi sebelum menyimpan data.
- Mengelola stok buku dengan memperhatikan jumlah buku yang sedang dipinjam.
- Menjaga riwayat transaksi agar tidak hilang ketika petugas menghapus buku.
Memahami Struktur Database CRUD Buku
Sebelum membuat fitur CRUD, kita perlu memahami struktur tabel books yang sudah kita siapkan pada tahap migration. Tabel ini menyimpan informasi buku, mulai dari kode, judul, penulis, penerbit, tahun terbit, hingga jumlah stok. Berikut struktur kolom tabel books:
| Kolom | Tipe Data | Keterangan |
|---|---|---|
| id | INT | Primary key |
| category_id | INT | Relasi ke tabel categories |
| code | VARCHAR(30) | Kode unik buku |
| title | VARCHAR(200) | Judul buku |
| author | VARCHAR(150) | Nama penulis |
| publisher | VARCHAR(150) | Nama penerbit |
| published_year | YEAR | Tahun terbit |
| stock_total | INT | Jumlah seluruh stok |
| stock_available | INT | Jumlah stok tersedia |
| is_active | TINYINT(1) | Status buku |
| created_at | DATETIME | Waktu pembuatan data |
| updated_at | DATETIME | Waktu perubahan data |
Perhatikan kolom category_id. Kolom ini menghubungkan tabel books dengan tabel categories. Relasi tersebut menggunakan konsep one-to-many. Artinya, satu kategori dapat memiliki banyak buku, sedangkan setiap buku hanya memiliki satu kategori. Selain itu, kita menggunakan dua kolom untuk mengelola stok:
stock_totalmenyimpan jumlah seluruh eksemplar buku.stock_availablemenyimpan jumlah eksemplar yang masih tersedia untuk dipinjam.
Sebagai contoh, perpustakaan memiliki 10 eksemplar buku. Jika 3 eksemplar sedang dipinjam, maka stok total bernilai 10 dan stok tersedia bernilai 7.
Membuat BookModel untuk CRUD Buku
Pertama, kita membuat Model untuk menghubungkan aplikasi dengan tabel books. Buka folder app/Models, kemudian buat file BookModel.php. Gunakan kode berikut:
<?php
namespace App\Models;
use CodeIgniter\Model;
class BookModel extends Model
{
protected $table = 'books';
protected $primaryKey = 'id';
protected $returnType = 'array';
protected $allowedFields = [
'category_id',
'code',
'title',
'author',
'publisher',
'published_year',
'stock_total',
'stock_available',
'is_active',
];
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
public function getBooksWithCategory()
{
return $this->select('books.*, categories.name AS category_name')
->join('categories', 'categories.id = books.category_id')
->orderBy('books.id', 'DESC')
->findAll();
}
}
Memahami kode BookModel
Mari kita pelajari beberapa bagian penting.
Pertama, menentukan tabel.
protected $table = 'books';
protected $primaryKey = 'id';
protected $returnType = 'array';
Kode tersebut menentukan tabel yang akan dikelola Model, primary key, dan bentuk data yang akan dikembalikan.
Kedua, menentukan allowedFields.
protected $allowedFields = [
'category_id',
'code',
'title',
'author',
'publisher',
'published_year',
'stock_total',
'stock_available',
'is_active',
];
Properti $allowedFields menentukan kolom yang boleh menerima data melalui proses insert dan update.
Ketiga, mengaktifkan timestamps.
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
Pengaturan tersebut membantu CodeIgniter mengelola kolom created_at dan updated_at.
Keempat, membuat method getBooksWithCategory().
public function getBooksWithCategory()
{
return $this->select('books.*, categories.name AS category_name')
->join('categories', 'categories.id = books.category_id')
->orderBy('books.id', 'DESC')
->findAll();
}
Method ini menggabungkan tabel books dan categories menggunakan JOIN.
Dengan demikian, halaman daftar buku dapat menampilkan nama kategori, bukan hanya angka category_id.
Membuat Controller CRUD Buku CodeIgniter 4
Setelah menyiapkan Model, selanjutnya kita membuat Controller untuk mengatur seluruh proses CRUD Buku.
Buka folder app/Controllers, kemudian buat file Books.php.
Gunakan kode berikut sesuai implementasi proyek SIPUS:
<?php
namespace App\Controllers;
use App\Models\BookModel;
use App\Models\CategoryModel;
class Books extends BaseController
{
public function index()
{
$model = new BookModel();
return view('books/index', [
'books' => $model->getBooksWithCategory(),
]);
}
public function new()
{
$categoryModel = new CategoryModel();
return view('books/form', [
'book' => null,
'categories' => $categoryModel->orderBy('name', 'ASC')->findAll(),
'errors' => session()->getFlashdata('errors') ?? [],
]);
}
public function create()
{
$rules = [
'category_id' => 'required|is_not_unique[categories.id]',
'code' => 'required|max_length[30]|is_unique[books.code]',
'title' => 'required|min_length[2]|max_length[200]',
'author' => 'required|max_length[150]',
'publisher' => 'permit_empty|max_length[150]',
'published_year' => 'permit_empty|integer|greater_than_equal_to[1000]|less_than_equal_to[' . date('Y') . ']',
'stock_total' => 'required|integer|greater_than_equal_to[0]',
];
if (! $this->validate($rules)) {
return redirect()->back()
->withInput()
->with('errors', $this->validator->getErrors());
}
$stockTotal = (int) $this->request->getPost('stock_total');
$model = new BookModel();
$model->insert([
'category_id' => $this->request->getPost('category_id'),
'code' => trim($this->request->getPost('code')),
'title' => trim($this->request->getPost('title')),
'author' => trim($this->request->getPost('author')),
'publisher' => $this->request->getPost('publisher') ?: null,
'published_year' => $this->request->getPost('published_year') ?: null,
'stock_total' => $stockTotal,
'stock_available'=> $stockTotal,
'is_active' => $this->request->getPost('is_active') ? 1 : 0,
]);
return redirect()->to('/books')
->with('success', 'Buku berhasil ditambahkan.');
}
public function edit($id)
{
$model = new BookModel();
$book = $model->find($id);
if (! $book) {
return redirect()->to('/books')
->with('error', 'Buku tidak ditemukan.');
}
$categoryModel = new CategoryModel();
return view('books/form', [
'book' => $book,
'categories' => $categoryModel->orderBy('name', 'ASC')->findAll(),
'errors' => session()->getFlashdata('errors') ?? [],
]);
}
public function update($id)
{
$model = new BookModel();
$book = $model->find($id);
if (! $book) {
return redirect()->to('/books')
->with('error', 'Buku tidak ditemukan.');
}
$rules = [
'category_id' => 'required|is_not_unique[categories.id]',
'code' => "required|max_length[30]|is_unique[books.code,id,{$id}]",
'title' => 'required|min_length[2]|max_length[200]',
'author' => 'required|max_length[150]',
'publisher' => 'permit_empty|max_length[150]',
'published_year' => 'permit_empty|integer|greater_than_equal_to[1000]|less_than_equal_to[' . date('Y') . ']',
'stock_total' => 'required|integer|greater_than_equal_to[0]',
];
if (! $this->validate($rules)) {
return redirect()->back()
->withInput()
->with('errors', $this->validator->getErrors());
}
$newStockTotal = (int) $this->request->getPost('stock_total');
// Hitung jumlah buku yang sedang dipinjam.
$borrowed = (int) $book['stock_total']
- (int) $book['stock_available'];
if ($newStockTotal < $borrowed) {
return redirect()->back()
->withInput()
->with('errors', [
'stock_total' =>
'Stok total tidak boleh lebih kecil daripada jumlah buku yang sedang dipinjam.',
]);
}
$model->update($id, [
'category_id' => $this->request->getPost('category_id'),
'code' => trim($this->request->getPost('code')),
'title' => trim($this->request->getPost('title')),
'author' => trim($this->request->getPost('author')),
'publisher' => $this->request->getPost('publisher') ?: null,
'published_year' => $this->request->getPost('published_year') ?: null,
'stock_total' => $newStockTotal,
'stock_available' => $newStockTotal - $borrowed,
'is_active' => $this->request->getPost('is_active') ? 1 : 0,
]);
return redirect()->to('/books')
->with('success', 'Buku berhasil diperbarui.');
}
public function delete($id)
{
$model = new BookModel();
$book = $model->find($id);
if (! $book) {
return redirect()->to('/books')
->with('error', 'Buku tidak ditemukan.');
}
// Pertahankan buku yang sudah tercatat dalam riwayat transaksi.
$used = db_connect()->table('loan_details')
->where('book_id', $id)
->countAllResults();
if ($used > 0) {
return redirect()->to('/books')
->with('error', 'Buku sudah memiliki riwayat transaksi dan tidak dapat dihapus.');
}
$model->delete($id);
return redirect()->to('/books')
->with('success', 'Buku berhasil dihapus.');
}
}
Memahami enam method utama
Controller Books memiliki enam method utama yang mengatur proses CRUD.
| Method | Fungsi |
|---|---|
index() | Menampilkan seluruh data buku |
new() | Menampilkan form tambah buku |
create() | Menyimpan buku baru |
edit($id) | Menampilkan form edit berdasarkan ID |
update($id) | Memperbarui data buku |
delete($id) | Menghapus data buku jika memenuhi syarat |
A. Method index()
Method index() membuat objek BookModel, kemudian memanggil getBooksWithCategory().
Selanjutnya, Controller mengirim hasil query ke View books/index.
Dengan cara ini, halaman daftar buku dapat menampilkan informasi buku sekaligus nama kategorinya.
B. Method new()
Method new() menampilkan form tambah buku.
Selain itu, method ini mengambil seluruh kategori dari CategoryModel. Kita mengurutkan kategori berdasarkan nama agar petugas lebih mudah memilih kategori melalui dropdown.
Controller juga mengirim $book => null sebagai penanda bahwa form sedang menjalankan mode tambah.
C. Method create()
Method create() menjalankan proses penyimpanan buku baru.
Sebelum menyimpan data, Controller menjalankan validasi berikut:
category_idwajib memilih kategori yang tersedia.codewajib diisi dan harus unik.titlewajib memiliki minimal 2 karakter dan maksimal 200 karakter.authorwajib diisi.publisherboleh kosong.published_yearboleh kosong, tetapi jika diisi harus berupa angka antara 1000 dan tahun sekarang.stock_totalwajib berupa angka dan tidak boleh negatif.
Jika data tidak memenuhi aturan, CodeIgniter mengembalikan pengguna ke form sebelumnya. Selanjutnya, withInput() mempertahankan input yang sudah pengguna masukkan, sedangkan with('errors', ...) mengirim pesan validasi.
Jika data memenuhi aturan, Controller menyimpan buku menggunakan insert().
Perhatikan bagian berikut:
$stockTotal = (int) $this->request->getPost('stock_total');
'stock_total' => $stockTotal,
'stock_available'=> $stockTotal,
Ketika petugas menambahkan buku baru, aplikasi menyamakan stok tersedia dengan stok total karena belum ada transaksi peminjaman.
D. Method edit($id)
Method edit($id) mengambil data buku berdasarkan ID.
Jika aplikasi tidak menemukan buku tersebut, Controller mengarahkan pengguna kembali ke halaman daftar dan menampilkan pesan kesalahan.
Sebaliknya, jika aplikasi menemukan buku, Controller mengambil data kategori dan mengirim seluruh data ke books/form.
Dengan demikian, form dapat menampilkan informasi buku yang ingin petugas ubah.
E. Method update($id)
Method update($id) memperbarui data buku berdasarkan ID.
Sebelum memperbarui data, Controller memeriksa keberadaan buku dan menjalankan validasi.
Perhatikan aturan kode buku berikut:
'code' => "required|max_length[30]|is_unique[books.code,id,{$id}]",
Aturan tersebut memeriksa keunikan kode buku dengan mengecualikan ID buku yang sedang kita edit. Jadi, petugas tetap dapat mempertahankan kode buku yang sama tanpa memicu kesalahan duplikasi.
Selanjutnya, Controller menghitung jumlah buku yang sedang dipinjam:
$borrowed = (int) $book['stock_total']
- (int) $book['stock_available'];
Sebagai contoh:
- Stok total sebelumnya: 10.
- Stok tersedia sebelumnya: 7.
- Jumlah buku yang sedang dipinjam: 3.
Jika petugas mengubah stok total menjadi 12, aplikasi menghitung stok tersedia menjadi 9.
Rumusnya:
Stok tersedia baru = Stok total baru − Jumlah buku yang sedang dipinjam
Namun, jika petugas memasukkan stok total yang lebih kecil daripada jumlah buku yang sedang dipinjam, Controller menolak perubahan tersebut.
Dengan aturan ini, aplikasi menjaga agar stok buku tetap masuk akal selama proses peminjaman berlangsung.
F. Method delete($id)
Method delete($id) menangani penghapusan data buku.
Sebelum menghapus data, Controller memeriksa keberadaan buku. Kemudian, Controller memeriksa tabel loan_details untuk mengetahui apakah buku sudah memiliki riwayat transaksi.
$used = db_connect()->table('loan_details')
->where('book_id', $id)
->countAllResults();
Jika hasil pemeriksaan lebih dari nol, Controller menolak penghapusan.
Mengapa kita menerapkan aturan tersebut?
Karena tabel transaksi menyimpan riwayat peminjaman. Jika petugas menghapus buku yang sudah pernah dipinjam, aplikasi berisiko kehilangan hubungan antara data buku dan riwayat transaksi.
Oleh karena itu, kita mempertahankan data buku yang sudah memiliki riwayat transaksi.
Membuat Halaman Daftar Buku dengan Bootstrap 5
Setelah menyelesaikan Controller, selanjutnya kita membuat halaman daftar buku.
Buat folder books di dalam app/Views, kemudian buat file index.php.
Gunakan kode berikut:
<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h3>Data Buku</h3>
<p class="text-muted mb-0">Kelola koleksi buku perpustakaan.</p>
</div>
<a href="<?= site_url('books/new') ?>" class="btn btn-primary">
Tambah Buku
</a>
</div>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success">
<?= esc(session()->getFlashdata('success')) ?>
</div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger">
<?= esc(session()->getFlashdata('error')) ?>
</div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-striped align-middle">
<thead class="table-light">
<tr>
<th>No.</th>
<th>Kode</th>
<th>Judul Buku</th>
<th>Kategori</th>
<th>Penulis</th>
<th>Stok</th>
<th>Status</th>
<th width="150">Aksi</th>
</tr>
</thead>
<tbody>
<?php if (!empty($books)): ?>
<?php $no = 1; ?>
<?php foreach ($books as $book): ?>
<tr>
<td><?= $no++ ?></td>
<td><?= esc($book['code']) ?></td>
<td><?= esc($book['title']) ?></td>
<td><?= esc($book['category_name']) ?></td>
<td><?= esc($book['author']) ?></td>
<td>
<?= esc($book['stock_available']) ?>
/
<?= esc($book['stock_total']) ?>
</td>
<td>
<?php if ($book['is_active']): ?>
<span class="badge bg-success">Aktif</span>
<?php else: ?>
<span class="badge bg-secondary">Nonaktif</span>
<?php endif; ?>
</td>
<td>
<a href="<?= site_url('books/edit/' . $book['id']) ?>"
class="btn btn-sm btn-warning">
Edit
</a>
<form action="<?= site_url('books/delete/' . $book['id']) ?>"
method="post"
class="d-inline"
onsubmit="return confirm('Yakin ingin menghapus buku ini?')">
<?= csrf_field() ?>
<button type="submit" class="btn btn-sm btn-danger">
Hapus
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="8" class="text-center">
Belum ada data buku.
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?= $this->endSection() ?>
Memahami halaman daftar buku
Kita menggunakan layout utama SIPUS melalui:
<?= $this->extend('layouts/main') ?>
Kemudian, bagian konten halaman menggunakan:
<?= $this->section('content') ?>
Dengan pendekatan tersebut, halaman daftar buku mengikuti navbar, sidebar, dan struktur utama yang sudah kita buat pada materi Layout SIPUS.
Selanjutnya, perhatikan penggunaan foreach. Perulangan ini menampilkan setiap buku ke dalam tabel.
Kita juga menggunakan esc() untuk membantu mengamankan output ketika aplikasi menampilkan data dari database.
Kolom stok menampilkan format stok tersedia dibandingkan stok total. Sebagai contoh, 7 / 10 berarti perpustakaan memiliki 10 eksemplar dan 7 eksemplar masih tersedia.
Membuat Form CRUD Buku
Selanjutnya, kita membuat satu form untuk dua kebutuhan, yaitu menambah dan mengedit buku.
Buat file form.php di dalam folder app/Views/books.
<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<?php
$book = $book ?? null;
$errors = $errors ?? [];
$isEdit = $book !== null;
?>
<div class="mb-4">
<h3><?= $isEdit ? 'Edit Buku' : 'Tambah Buku' ?></h3>
<p class="text-muted">Lengkapi informasi buku perpustakaan.</p>
</div>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<strong>Periksa kembali data berikut:</strong>
<ul class="mb-0">
<?php foreach ($errors as $error): ?>
<li><?= esc($error) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<form action="<?= $isEdit
? site_url('books/update/' . $book['id'])
: site_url('books/create') ?>"
method="post">
<?= csrf_field() ?>
<div class="mb-3">
<label class="form-label">Kategori</label>
<select name="category_id" class="form-select" required>
<option value="">-- Pilih Kategori --</option>
<?php foreach ($categories as $category): ?>
<option value="<?= $category['id'] ?>"
<?= old('category_id', $book['category_id'] ?? '') == $category['id'] ? 'selected' : '' ?>>
<?= esc($category['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label">Kode Buku</label>
<input type="text"
name="code"
class="form-control"
maxlength="30"
value="<?= esc(old('code', $book['code'] ?? '')) ?>"
required>
</div>
<div class="mb-3">
<label class="form-label">Judul Buku</label>
<input type="text"
name="title"
class="form-control"
maxlength="200"
value="<?= esc(old('title', $book['title'] ?? '')) ?>"
required>
</div>
<div class="mb-3">
<label class="form-label">Penulis</label>
<input type="text"
name="author"
class="form-control"
maxlength="150"
value="<?= esc(old('author', $book['author'] ?? '')) ?>"
required>
</div>
<div class="mb-3">
<label class="form-label">Penerbit</label>
<input type="text"
name="publisher"
class="form-control"
maxlength="150"
value="<?= esc(old('publisher', $book['publisher'] ?? '')) ?>">
</div>
<div class="mb-3">
<label class="form-label">Tahun Terbit</label>
<input type="number"
name="published_year"
class="form-control"
min="1000"
max="<?= date('Y') ?>"
value="<?= esc(old('published_year', $book['published_year'] ?? '')) ?>">
</div>
<div class="mb-3">
<label class="form-label">Stok Total</label>
<input type="number"
name="stock_total"
class="form-control"
min="0"
value="<?= esc(old('stock_total', $book['stock_total'] ?? 0)) ?>"
required>
<small class="text-muted">
Masukkan jumlah seluruh eksemplar buku.
</small>
</div>
<div class="form-check mb-4">
<input type="checkbox"
name="is_active"
value="1"
class="form-check-input"
id="is_active"
<?= old('is_active', $book['is_active'] ?? 1) ? 'checked' : '' ?>>
<label class="form-check-label" for="is_active">
Buku aktif
</label>
</div>
<button type="submit" class="btn btn-primary">
<?= $isEdit ? 'Update Buku' : 'Simpan Buku' ?>
</button>
<a href="<?= site_url('books') ?>" class="btn btn-secondary">
Kembali
</a>
</form>
</div>
</div>
<?= $this->endSection() ?>
Mengapa kita menggunakan satu form?
Kita menggunakan variabel $isEdit untuk menentukan mode form.
- Jika
$bookbernilainull, form menampilkan mode tambah. - Jika
$bookberisi data buku, form menampilkan mode edit.
Dengan cara ini, kita tidak perlu membuat dua file form yang memiliki kode hampir sama.
Selain itu, fungsi old() membantu mengisi kembali input ketika validasi gagal. Jadi, petugas tidak perlu mengetik ulang seluruh data.
Perhatikan juga bagian dropdown kategori. Form mengambil data dari $categories, kemudian menampilkan nama kategori dan menggunakan ID kategori sebagai nilai pilihan.
Mengatur Routes CRUD Buku
Setelah menyelesaikan Model, Controller, dan View, selanjutnya kita mengatur URL melalui file app/Config/Routes.php.
Tambahkan route berikut:
$routes->get('books', 'Books::index');
$routes->get('books/new', 'Books::new');
$routes->post('books/create', 'Books::create');
$routes->get('books/edit/(:num)', 'Books::edit/$1');
$routes->post('books/update/(:num)', 'Books::update/$1');
$routes->post('books/delete/(:num)', 'Books::delete/$1');
Perhatikan penggunaan $1 pada route edit, update, dan delete. Bagian tersebut meneruskan angka dari URL ke parameter $id pada Controller.
Sebagai contoh, URL books/edit/5 akan memanggil method edit(5).
Jangan menulis angka ID secara langsung seperti Books::edit/1. Jika kita menggunakan angka tetap, aplikasi akan selalu membuka data dengan ID yang sama.
Pengujian CRUD Buku CodeIgniter 4
Sekarang kita dapat menjalankan aplikasi dan menguji seluruh fitur.
Buka terminal pada folder proyek SIPUS, kemudian jalankan:
php spark serve
Selanjutnya, buka alamat berikut pada browser:
http://localhost:8080/books
Lakukan pengujian secara berurutan.
A. Menguji Tambah Buku
- Buka halaman Data Buku.
- Klik tombol Tambah Buku.
- Pilih kategori.
- Masukkan kode dan judul buku.
- Isi nama penulis dan penerbit.
- Masukkan tahun terbit dan stok total.
- Tentukan status aktif.
- Klik Simpan Buku.
Jika seluruh input memenuhi aturan validasi, aplikasi akan menyimpan buku dan menampilkan pesan keberhasilan.
B. Menguji Daftar Buku
Setelah menambahkan buku, periksa halaman Data Buku.
Pastikan aplikasi menampilkan kode, judul, kategori, penulis, stok, dan status buku dengan benar.
C. Menguji Edit Buku
Klik tombol Edit pada salah satu baris buku.
Kemudian, ubah judul, kategori, atau informasi lainnya. Klik Update Buku dan periksa hasilnya pada halaman daftar.
Pastikan aplikasi memperbarui data berdasarkan ID buku yang kita pilih, bukan selalu mengubah data pertama.
D. Menguji Hapus Buku
Klik tombol Hapus pada salah satu buku yang belum memiliki riwayat transaksi.
Aplikasi akan menampilkan konfirmasi sebelum menjalankan proses penghapusan.
Namun, jika buku sudah memiliki riwayat transaksi pada loan_details, Controller akan menolak penghapusan dan menampilkan pesan kesalahan.
Mengelola Stok Buku pada Aplikasi SIPUS
Salah satu bagian penting dalam modul Buku adalah pengelolaan stok.
Kita tidak boleh menganggap stock_total dan stock_available sebagai dua angka yang berdiri sendiri.
Misalnya, perpustakaan memiliki 12 eksemplar buku. Kemudian, 4 eksemplar sedang dipinjam.
Maka:
- Stok total: 12.
- Stok tersedia: 8.
- Jumlah dipinjam: 4.
Jika petugas mengubah stok total menjadi 15, aplikasi menghitung stok tersedia menjadi 11.
Rumusnya:
Stok tersedia = Stok total − Jumlah buku yang sedang dipinjam
Dengan rumus tersebut, aplikasi tetap menjaga jumlah stok agar sesuai dengan transaksi peminjaman.
Pada tahap berikutnya, kita akan menghubungkan proses peminjaman dan pengembalian dengan stok buku. Kita juga akan mempelajari database transaction agar penyimpanan transaksi dan perubahan stok berjalan secara konsisten.
Kesimpulan Tutorial CRUD Buku CodeIgniter 4
Pada materi ini, kita telah membangun fitur CRUD Buku untuk aplikasi SIPUS menggunakan CodeIgniter 4 dan Bootstrap 5.
Kita mulai dengan membuat BookModel, kemudian mengembangkan Books Controller, membuat halaman daftar buku, dan menyusun form tambah serta edit. Setelah itu, kita mengatur route dan menguji seluruh proses CRUD.
Selain mempelajari operasi dasar database, kita juga mengenal relasi tabel, validasi input, pengelolaan stok, dan perlindungan riwayat transaksi.
Dengan demikian, fitur Buku menjadi fondasi penting sebelum kita mengembangkan modul Anggota, Peminjaman, dan Pengembalian.
11. Latihan Mandiri
Untuk memperkuat pemahaman, kerjakan latihan berikut:
- Tambahkan kolom pencarian berdasarkan judul buku.
- Tambahkan filter berdasarkan kategori.
- Urutkan daftar buku berdasarkan judul.
- Tampilkan jumlah seluruh buku pada halaman daftar.
- Tambahkan informasi jumlah buku yang tersedia.
- Buat fitur untuk menampilkan buku aktif saja.
- Jelaskan mengapa aplikasi tidak boleh menghapus buku yang sudah memiliki riwayat transaksi.
Tantangan tambahan: Buat halaman detail buku yang menampilkan informasi lengkap buku dan riwayat peminjamannya.
Materi Selanjutnya
Setelah menyelesaikan CRUD Buku, kita akan melanjutkan pengembangan SIPUS ke modul CRUD Anggota Perpustakaan.
Pada materi tersebut, kita akan mengelola identitas anggota, nomor anggota, alamat, nomor telepon, serta status keanggotaan. Modul Anggota juga menjadi bagian penting dalam proses transaksi peminjaman buku. (ms)