Laravel · Bab 7
Lab 4: Form, CSRF & Validasi
Membuat form tambah produk yang aman dengan token @csrf, memvalidasi input di sisi server, menampilkan pesan galat per kolom, lalu menyimpan data dengan Eloquent.
Di lab ini katalog Smart Retail App bisa diisi: kamu membuat form tambah produk, memvalidasi setiap kolom di server, dan menyimpan data yang lolos validasi. Contoh kode memakai studi kasus perpustakaan (books dan authors); terapkan polanya ke produk dan kategori sesuai aturan validasi di Alur Langkah.
Alur Langkah
- Di controller produk, tambahkan method
create()yang mengambil semua kategori dan mengirimkannya ke view form. - Tambahkan method
store(Request $request)yang memvalidasiproduct_code(wajib, unik, maks. 10 karakter),name(wajib, 3–100 karakter),category_id(wajib, harus ada di tabel kategori),price(wajib, angka, min. 500), danstock(wajib, bilangan bulat, min. 0), dengan pesan kustom untuk kode kembar, kategori tidak valid, dan harga terlalu kecil. Setelah itu simpan data dan redirect ke katalog dengan pesan sukses. - Buat view
create.blade.phpberisi form: kode produk, dropdown kategori, nama, harga, stok awal, serta tombol Cancel dan Save Product. - Buka halaman katalog, klik Add Product, lalu coba kirim form kosong, kode kembar, dan data yang benar.
Method create() & store()
create() hanya menyiapkan data untuk form, misalnya daftar penulis untuk dropdown:
public function create()
{
$authors = Author::all();
return view('books.create', compact('authors'));
}
Validasi Server-Side
Validasi di server adalah pertahanan utama. Validasi di peramban (atribut HTML required) mudah dilewati, sedangkan $request->validate selalu berjalan sebelum data menyentuh database. Jika ada aturan yang gagal, Laravel otomatis mengembalikan pengguna ke form beserta pesan galat dan input sebelumnya.
public function store(Request $request)
{
$validated = $request->validate([
'isbn' => 'required|unique:books,isbn|max:13',
'title' => 'required|min:3|max:100',
'author_id' => 'required|exists:authors,id',
'price' => 'required|numeric|min:500',
'stock' => 'required|integer|min:0',
], [
'isbn.unique' => 'ISBN sudah terdaftar!',
]);
Book::create($validated);
return redirect()->route('books.index')->with('success', 'Buku berhasil ditambahkan!');
}
| Aturan | Arti |
|---|---|
required | Wajib diisi |
unique:tabel,kolom | Nilai belum pernah dipakai di kolom tersebut |
exists:tabel,kolom | Nilai harus ada di tabel lain (mencegah ID kategori palsu) |
numeric | Harus angka (boleh desimal) |
integer | Harus bilangan bulat |
min:n / max:n | Batas nilai untuk angka, atau batas panjang untuk teks |
Array kedua berisi pesan kustom dengan format 'kolom.aturan' => 'pesan'. Hasil validasi ($validated) langsung disimpan dengan Model::create — karena itulah semua kolomnya harus terdaftar di $fillable. Terakhir, ->with('success', ...) mengirim pesan yang ditampilkan kotak sukses di layout.
Form Blade: @csrf, old() & @error
<form action="{{ route('books.store') }}" method="POST">
@csrf
<label class="form-label">Judul Buku</label>
<input type="text" name="title"
class="form-control @error('title') is-invalid @enderror"
value="{{ old('title') }}">
@error('title')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
<label class="form-label">Penulis</label>
<select name="author_id" class="form-select @error('author_id') is-invalid @enderror">
<option value="">-- Pilih Penulis --</option>
@foreach($authors as $author)
<option value="{{ $author->id }}" {{ old('author_id') == $author->id ? 'selected' : '' }}>
{{ $author->name }}
</option>
@endforeach
</select>
<button type="submit" class="btn btn-primary">Simpan</button>
</form>
@csrfmenyisipkan token tersembunyi yang wajib ada di setiap form POST (Bab 2).old('title')mengisi ulang input dengan nilai sebelumnya ketika validasi gagal, sehingga pengguna tidak perlu mengetik ulang. Bentukold('stock', 0)memberi nilai awal.@error('title')…@enderrorhanya tampil bila kolom itu gagal validasi;$messageberisi pesan galatnya.- Kelas Bootstrap
is-invalidmemberi bingkai merah dan memunculkaninvalid-feedback.
Hasil yang Diharapkan
Form kosong atau kode produk kembar ditolak dengan pesan merah di bawah kolom yang salah, dan isian lain tetap terisi. Data yang benar tersimpan, lalu kamu kembali ke katalog dengan kotak pesan hijau dan produk baru di baris teratas.