# Cara Membuat CRUD Operation di Laravel: Panduan Lengkap dengan Contoh
Membuat aplikasi web yang dinamis dan interaktif seringkali membutuhkan kemampuan untuk mengelola data. CRUD (Create, Read, Update, Delete) operation adalah fondasi dari pengelolaan data ini. Laravel, dengan sintaks yang elegan dan fitur-fiturnya yang kaya, mempermudah implementasi CRUD operation. Dalam panduan lengkap ini, kita akan membahas langkah demi langkah **cara membuat CRUD operation di Laravel** dengan contoh praktis dan mudah dipahami. Siap memulai petualangan pemrograman kita? Mari kita mulai!
## 1. Apa Itu CRUD Operation dan Mengapa Penting di Laravel?
CRUD adalah singkatan dari Create, Read, Update, dan Delete. Ini adalah empat fungsi dasar yang digunakan untuk mengelola data dalam database. CRUD operation memungkinkan pengguna untuk:
* **Create (Membuat):** Menambahkan data baru ke dalam database.
* **Read (Membaca):** Menampilkan data yang sudah ada dari database.
* **Update (Memperbarui):** Mengubah data yang sudah ada di dalam database.
* **Delete (Menghapus):** Menghapus data dari database.
Mengapa CRUD penting di Laravel? Laravel menyediakan tools yang kuat dan mudah digunakan untuk berinteraksi dengan database. Fitur-fitur seperti Eloquent ORM (Object-Relational Mapping) menyederhanakan proses pembuatan query dan pengelolaan data. Dengan menggunakan Laravel, developer dapat fokus pada logika bisnis aplikasi daripada terjebak dalam kompleksitas query SQL. Laravel juga menyediakan berbagai kemudahan validasi dan otorisasi yang membuat aplikasi CRUD lebih aman dan reliable.
## 2. Persiapan Awal: Instalasi Laravel dan Konfigurasi Database
Sebelum kita mulai membuat CRUD operation, kita perlu menyiapkan environment Laravel kita. Berikut adalah langkah-langkahnya:
* **Instalasi Laravel:** Pastikan PHP dan Composer sudah terinstall di komputer Anda. Buka terminal atau command prompt dan jalankan perintah berikut:
```bash
composer create-project --prefer-dist laravel/laravel nama-proyek
cd nama-proyek
Ganti `nama-proyek` dengan nama proyek yang Anda inginkan.
-
Konfigurasi Database: Setelah Laravel terinstall, kita perlu mengkonfigurasi koneksi database. Buka file
.envdi direktori proyek Anda. Cari bagian yang dimulai denganDB_. Ubah nilai-nilai berikut sesuai dengan konfigurasi database Anda:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nama_database DB_USERNAME=nama_pengguna DB_PASSWORD=password_databaseGanti
nama_database,nama_pengguna, danpassword_databasedengan kredensial database Anda. Jika Anda menggunakan database selain MySQL, ubah nilaiDB_CONNECTIONsesuai dengan jenis database yang Anda gunakan (misalnya,pgsqluntuk PostgreSQL,sqliteuntuk SQLite).Penting: Jangan lupa membuat database yang sudah dikonfigurasi di server database Anda.
3. Membuat Model dan Migration: Dasar Struktur Data CRUD
Setelah environment siap, mari kita definisikan struktur data kita. Kita akan membuat model dan migration untuk entitas yang akan kita kelola (misalnya, “Produk”).
-
Membuat Model: Gunakan perintah Artisan berikut untuk membuat model:
php artisan make:model Produk -mPerintah ini akan membuat file
app/Models/Produk.phpdan file migration terkait di direktoridatabase/migrations. Opsi-motomatis membuat file migration. -
Definisi Migration: Buka file migration yang baru dibuat (biasanya namanya diawali dengan tanggal dan diakhiri dengan
create_produks_table.php). Modifikasi methodup()untuk mendefinisikan skema tabel. Misalnya, untuk tabel “produks” dengan kolomnama,deskripsi, danharga, tambahkan kode berikut:<?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('produks', function (Blueprint $table) { $table->id(); $table->string('nama'); $table->text('deskripsi')->nullable(); $table->decimal('harga', 10, 2); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('produks'); } };Penjelasan:
$table->id();: Membuat kolomidsebagai primary key (auto-incrementing integer).$table->string('nama');: Membuat kolomnamadengan tipe data string (VARCHAR).$table->text('deskripsi')->nullable();: Membuat kolomdeskripsidengan tipe data text dan boleh kosong (nullable).$table->decimal('harga', 10, 2);: Membuat kolomhargadengan tipe data decimal, panjang 10 digit dan 2 digit desimal.$table->timestamps();: Membuat kolomcreated_atdanupdated_atuntuk menyimpan timestamp pembuatan dan pembaruan data.
-
Menjalankan Migration: Setelah mendefinisikan skema tabel, jalankan perintah Artisan berikut untuk membuat tabel di database:
php artisan migratePerintah ini akan menjalankan semua migration yang belum dieksekusi.
4. Membuat Controller: Menangani Logika CRUD
Controller bertanggung jawab untuk menangani request HTTP dan berinteraksi dengan model untuk melakukan CRUD operation.
-
Membuat Controller: Gunakan perintah Artisan berikut untuk membuat controller:
php artisan make:controller ProdukController --resourceOpsi
--resourceakan membuat controller dengan method-method standar untuk CRUD operation (index, create, store, show, edit, update, destroy). -
Implementasi Method Controller: Buka file
app/Http/Controllers/ProdukController.php. Kita akan implementasikan masing-masing method CRUD:<?php namespace AppHttpControllers; use AppModelsProduk; use IlluminateHttpRequest; class ProdukController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { $produks = Produk::all(); return view('produks.index', compact('produks')); } /** * Show the form for creating a new resource. * * @return IlluminateHttpResponse */ public function create() { return view('produks.create'); } /** * Store a newly created resource in storage. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */ public function store(Request $request) { $request->validate([ 'nama' => 'required', 'deskripsi' => 'nullable', 'harga' => 'required|numeric', ]); Produk::create($request->all()); return redirect()->route('produks.index') ->with('success','Produk berhasil ditambahkan.'); } /** * Display the specified resource. * * @param AppModelsProduk $produk * @return IlluminateHttpResponse */ public function show(Produk $produk) { return view('produks.show',compact('produk')); } /** * Show the form for editing the specified resource. * * @param AppModelsProduk $produk * @return IlluminateHttpResponse */ public function edit(Produk $produk) { return view('produks.edit',compact('produk')); } /** * Update the specified resource in storage. * * @param IlluminateHttpRequest $request * @param AppModelsProduk $produk * @return IlluminateHttpResponse */ public function update(Request $request, Produk $produk) { $request->validate([ 'nama' => 'required', 'deskripsi' => 'nullable', 'harga' => 'required|numeric', ]); $produk->update($request->all()); return redirect()->route('produks.index') ->with('success','Produk berhasil diperbarui.'); } /** * Remove the specified resource from storage. * * @param AppModelsProduk $produk * @return IlluminateHttpResponse */ public function destroy(Produk $produk) { $produk->delete(); return redirect()->route('produks.index') ->with('success','Produk berhasil dihapus.'); } }Penjelasan:
index(): Menampilkan daftar semua produk. Mengambil semua data dari tabelproduksmenggunakanProduk::all()dan mengirimkannya ke viewproduks.index.create(): Menampilkan form untuk membuat produk baru. Menampilkan viewproduks.create.store(Request $request): Menyimpan produk baru ke database. Melakukan validasi input menggunakan$request->validate()dan kemudian membuat instance baru dari modelProdukmenggunakanProduk::create($request->all()).$request->all()akan mengambil semua data dari form. Setelah berhasil, redirect ke halaman index dengan pesan sukses.show(Produk $produk): Menampilkan detail sebuah produk. Menerima instanceProduksebagai parameter (route model binding) dan mengirimkannya ke viewproduks.show.edit(Produk $produk): Menampilkan form untuk mengedit sebuah produk. Menerima instanceProduksebagai parameter dan mengirimkannya ke viewproduks.edit.update(Request $request, Produk $produk): Memperbarui produk yang sudah ada di database. Melakukan validasi input dan kemudian memperbarui instanceProdukmenggunakan$produk->update($request->all()).destroy(Produk $produk): Menghapus produk dari database. Menghapus instanceProdukmenggunakan$produk->delete().
5. Membuat View: Antarmuka Pengguna CRUD
View adalah tampilan antarmuka pengguna yang berinteraksi dengan controller untuk menampilkan data dan menerima input dari pengguna. Kita akan membuat view untuk setiap operasi CRUD.
-
Membuat Direktori View: Buat direktori
resources/views/produksuntuk menyimpan semua view terkait produk. -
Membuat View
index.blade.php: View ini menampilkan daftar semua produk.<!-- resources/views/produks/index.blade.php --> <!DOCTYPE html> <html> <head> <title>Daftar Produk</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <h1>Daftar Produk</h1> <a href="{{ route('produks.create') }}" class="btn btn-success mb-3">Tambah Produk</a> @if ($message = Session::get('success')) <div class="alert alert-success"> <p>{{ $message }}</p> </div> @endif <table class="table table-bordered"> <tr> <th>ID</th> <th>Nama</th> <th>Deskripsi</th> <th>Harga</th> <th>Aksi</th> </tr> @foreach ($produks as $produk) <tr> <td>{{ $produk->id }}</td> <td>{{ $produk->nama }}</td> <td>{{ $produk->deskripsi }}</td> <td>{{ $produk->harga }}</td> <td> <form action="{{ route('produks.destroy',$produk->id) }}" method="POST"> <a class="btn btn-info" href="{{ route('produks.show',$produk->id) }}">Lihat</a> <a class="btn btn-primary" href="{{ route('produks.edit',$produk->id) }}">Edit</a> @csrf @method('DELETE') <button type="submit" class="btn btn-danger">Hapus</button> </form> </td> </tr> @endforeach </table> </div> </body> </html> -
Membuat View
create.blade.php: View ini menampilkan form untuk membuat produk baru.<!-- resources/views/produks/create.blade.php --> <!DOCTYPE html> <html> <head> <title>Tambah Produk</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <h1>Tambah Produk</h1> <form action="{{ route('produks.store') }}" method="POST"> @csrf <div class="mb-3"> <label for="nama" class="form-label">Nama:</label> <input type="text" class="form-control" id="nama" name="nama" required> </div> <div class="mb-3"> <label for="deskripsi" class="form-label">Deskripsi:</label> <textarea class="form-control" id="deskripsi" name="deskripsi"></textarea> </div> <div class="mb-3"> <label for="harga" class="form-label">Harga:</label> <input type="number" step="0.01" class="form-control" id="harga" name="harga" required> </div> <button type="submit" class="btn btn-primary">Simpan</button> </form> </div> </body> </html> -
Membuat View
show.blade.php: View ini menampilkan detail sebuah produk.<!-- resources/views/produks/show.blade.php --> <!DOCTYPE html> <html> <head> <title>Detail Produk</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <h1>Detail Produk</h1> <div class="mb-3"> <strong>ID:</strong> {{ $produk->id }} </div> <div class="mb-3"> <strong>Nama:</strong> {{ $produk->nama }} </div> <div class="mb-3"> <strong>Deskripsi:</strong> {{ $produk->deskripsi }} </div> <div class="mb-3"> <strong>Harga:</strong> {{ $produk->harga }} </div> <a class="btn btn-primary" href="{{ route('produks.index') }}">Kembali</a> </div> </body> </html> -
Membuat View
edit.blade.php: View ini menampilkan form untuk mengedit sebuah produk.<!-- resources/views/produks/edit.blade.php --> <!DOCTYPE html> <html> <head> <title>Edit Produk</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <h1>Edit Produk</h1> <form action="{{ route('produks.update', $produk->id) }}" method="POST"> @csrf @method('PUT') <div class="mb-3"> <label for="nama" class="form-label">Nama:</label> <input type="text" class="form-control" id="nama" name="nama" value="{{ $produk->nama }}" required> </div> <div class="mb-3"> <label for="deskripsi" class="form-label">Deskripsi:</label> <textarea class="form-control" id="deskripsi" name="deskripsi">{{ $produk->deskripsi }}</textarea> </div> <div class="mb-3"> <label for="harga" class="form-label">Harga:</label> <input type="number" step="0.01" class="form-control" id="harga" name="harga" value="{{ $produk->harga }}" required> </div> <button type="submit" class="btn btn-primary">Simpan Perubahan</button> </form> </div> </body> </html>Penjelasan:
- Setiap view menggunakan Bootstrap untuk styling dasar.
- View
index.blade.phpmenggunakan loop@foreachuntuk menampilkan daftar produk. - View
create.blade.phpdanedit.blade.phpmenggunakan form HTML untuk menerima input dari pengguna. - View
edit.blade.phpmenggunakan@method('PUT')untuk mengirimkan request PUT. Laravel menggunakan PUT untuk update karena konvensi RESTful.
6. Konfigurasi Route: Menghubungkan Request ke Controller
Route menentukan bagaimana aplikasi merespon request HTTP tertentu. Kita akan mengkonfigurasi route untuk menghubungkan request ke method-method di ProdukController.
-
Menggunakan Resource Route: Buka file
routes/web.phpdan tambahkan route berikut:<?php use IlluminateSupportFacadesRoute; use AppHttpControllersProdukController; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::resource('produks', ProdukController::class);Route::resource('produks', ProdukController::class)secara otomatis membuat route untuk semua method CRUD diProdukController. Ini adalah cara yang ringkas untuk mendefinisikan route CRUD.Rincian Route yang Dibuat:
HTTP Verb URI Action Route Name GET /produks index produks.index GET /produks/create create produks.create POST /produks store produks.store GET /produks/{produk} show produks.show GET /produks/{produk}/edit edit produks.edit PUT/PATCH /produks/{produk} update produks.update DELETE /produks/{produk} destroy produks.destroy
7. Validasi Data: Mengamankan Input Pengguna
Validasi data sangat penting untuk memastikan integritas data dan mencegah kerentanan keamanan. Kita sudah menggunakan validasi sederhana di method store() dan update() di ProdukController. Kita bisa memperluas validasi ini lebih lanjut.
-
Membuat Request Class: Untuk validasi yang lebih kompleks, kita bisa membuat request class. Gunakan perintah Artisan berikut:
php artisan make:request StoreProdukRequest php artisan make:request UpdateProdukRequest -
Definisi Validasi: Buka file
app/Http/Requests/StoreProdukRequest.phpdanapp/Http/Requests/UpdateProdukRequest.php. Modifikasi methodrules()untuk mendefinisikan aturan validasi:// app/Http/Requests/StoreProdukRequest.php <?php namespace AppHttpRequests; use IlluminateFoundationHttpFormRequest; class StoreProdukRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; // Ubah ke false jika butuh otorisasi lebih lanjut } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'nama' => 'required|string|max:255', 'deskripsi' => 'nullable|string', 'harga' => 'required|numeric|min:0', ]; } } // app/Http/Requests/UpdateProdukRequest.php <?php namespace AppHttpRequests; use IlluminateFoundationHttpFormRequest; class UpdateProdukRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; // Ubah ke false jika butuh otorisasi lebih lanjut } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'nama' => 'required|string|max:255', 'deskripsi' => 'nullable|string', 'harga' => 'required|numeric|min:0', ]; } }Penjelasan:
'nama' => 'required|string|max:255': Kolomnamawajib diisi, bertipe data string, dan panjang maksimal 255 karakter.'deskripsi' => 'nullable|string': Kolomdeskripsiboleh kosong dan bertipe data string.'harga' => 'required|numeric|min:0': Kolomhargawajib diisi, bertipe data numeric, dan minimal 0.
-
Menggunakan Request Class di Controller: Ganti
Request $requestdenganStoreProdukRequest $requestdanUpdateProdukRequest $requestdi methodstore()danupdate()diProdukController.public function store(StoreProdukRequest $request) { Produk::create($request->all()); return redirect()->route('produks.index') ->with('success','Produk berhasil ditambahkan.'); } public function update(UpdateProdukRequest $request, Produk $produk) { $produk->update($request->all()); return redirect()->route('produks.index') ->with('success','Produk berhasil diperbarui.'); }Laravel akan secara otomatis menjalankan validasi yang didefinisikan di request class sebelum mengeksekusi logika controller. Jika validasi gagal, Laravel akan secara otomatis redirect kembali ke form dengan pesan error.
8. Implementasi Otorisasi: Membatasi Akses ke Data
Otorisasi memastikan bahwa hanya pengguna yang berwenang yang dapat mengakses atau memodifikasi data. Laravel menyediakan sistem otorisasi yang fleksibel dan mudah digunakan.
-
Membuat Policy: Gunakan perintah Artisan berikut untuk membuat policy untuk model
Produk:php artisan make:policy ProdukPolicy --model=Produk -
Definisi Policy: Buka file
app/Policies/ProdukPolicy.php. Kita akan mendefinisikan method untuk setiap operasi CRUD (view, create, update, delete). Asumsikan kita memiliki modelUserdan kita ingin hanya user dengan role “admin” yang bisa mengelola produk.<?php namespace AppPolicies; use AppModelsUser; use AppModelsProduk; use IlluminateAuthAccessHandlesAuthorization; class ProdukPolicy { use HandlesAuthorization; /** * Determine whether the user can view any models. * * @param AppModelsUser $user * @return IlluminateAuthAccessResponse|bool */ public function viewAny(User $user) { return $user->role === 'admin'; } /** * Determine whether the user can view the model. * * @param AppModelsUser $user * @param AppModelsProduk $produk * @return IlluminateAuthAccessResponse|bool */ public function view(User $user, Produk $produk) { return $user->role === 'admin'; } /** * Determine whether the user can create models. * * @param AppModelsUser $user * @return IlluminateAuthAccessResponse|bool */ public function create(User $user) { return $user->role === 'admin'; } /** * Determine whether the user can update the model. * * @param AppModelsUser $user * @param AppModelsProduk $produk * @return IlluminateAuthAccessResponse|bool */ public function update(User $user, Produk $produk) { return $user->role === 'admin'; } /** * Determine whether the user can delete the model. * * @param AppModelsUser $user * @param AppModelsProduk $produk * @return IlluminateAuthAccessResponse|bool */ public function delete(User $user, Produk $produk) { return $user->role === 'admin'; } /** * Determine whether the user can restore the model. * * @param AppModelsUser $user * @param AppModelsProduk $produk * @return IlluminateAuthAccessResponse|bool */ public function restore(User $user, Produk $produk) { // Otorisasi untuk restore, jika ada soft delete return $user->role === 'admin'; } /** * Determine whether the user can permanently delete the model. * * @param AppModelsUser $user * @param AppModelsProduk $produk * @return IlluminateAuthAccessResponse|bool */ public function forceDelete(User $user, Produk $produk) { // Otorisasi untuk force delete, jika ada soft delete return $user->role === 'admin'; } } -
Register Policy: Buka file
app/Providers/AuthServiceProvider.phpdan tambahkan policy ke property$policies:<?php namespace AppProviders; use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider; use IlluminateSupportFacadesGate; use AppModelsProduk; use AppPoliciesProdukPolicy; class AuthServiceProvider extends ServiceProvider { /** * The model to policy mappings for the application. * * @var array<class-string, class-string> */ protected $policies = [ Produk::class => ProdukPolicy::class, ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); // } } -
Menggunakan Policy di Controller: Gunakan method
authorize()di controller untuk memeriksa otorisasi sebelum menjalankan logika CRUD.public function index() { $this->authorize('viewAny', Produk::class); // Otorisasi untuk menampilkan daftar $produks = Produk::all(); return view('produks.index', compact('produks')); } public function create() { $this->authorize('create', Produk::class); // Otorisasi untuk membuat return view('produks.create'); } public function store(StoreProdukRequest $request) { $this->authorize('create', Produk::class); // Otorisasi untuk membuat Produk::create($request->all()); return redirect()->route('produks.index') ->with('success','Produk berhasil ditambahkan.'); } public function show(Produk $produk) { $this->authorize('view', $produk); // Otorisasi untuk melihat detail return view('produks.show',compact('produk')); } public function edit(Produk $produk) { $this->authorize('update', $produk); // Otorisasi untuk mengedit return view('produks.edit',compact('produk')); } public function update(UpdateProdukRequest $request, Produk $produk) { $this->authorize('update', $produk); // Otorisasi untuk mengedit $produk->update($request->all()); return redirect()->route('produks.index') ->with('success','Produk berhasil diperbarui.'); } public function destroy(Produk $produk) { $this->authorize('delete', $produk); // Otorisasi untuk menghapus $produk->delete(); return redirect()->route('produks.index') ->with('success','Produk berhasil dihapus.'); }Jika user tidak memiliki izin, Laravel akan secara otomatis melempar exception
IlluminateAuthAccessAuthorizationExceptionyang akan dihandle oleh exception handler. Anda bisa mengkonfigurasi exception handler untuk menampilkan pesan error yang sesuai.
9. Fitur Tambahan: Pagination, Search, dan Soft Deletes
Berikut adalah beberapa fitur tambahan yang bisa Anda tambahkan ke aplikasi CRUD Anda:
-
Pagination: Untuk menampilkan data dalam jumlah besar, gunakan pagination. Ganti
Produk::all()denganProduk::paginate(10)di methodindex()di controller. Kemudian, tambahkan link pagination di viewindex.blade.phpmenggunakan{{ $produks->links() }}. -
Search: Tambahkan form search ke view
index.blade.php. Di controller, modifikasi query untuk memfilter data berdasarkan keyword search.public function index(Request $request) { $keyword = $request->get('keyword'); $produks = Produk::query(); if($keyword){ $produks->where('nama', 'LIKE', "%$keyword%") ->orWhere('deskripsi', 'LIKE', "%$keyword%"); } $produks = $produks->paginate(10); return view('produks.index', compact('produks', 'keyword')); } -
Soft Deletes: Untuk tidak benar-benar menghapus data dari database, gunakan soft deletes. Tambahkan
use SoftDeletes;ke modelProduk. Tambahkan kolomdeleted_atke tabelproduksmenggunakan migration. Ganti$produk->delete()dengan$produk->delete()di methoddestroy()di controller. Untuk menampilkan data yang tidak dihapus, gunakanProduk::withTrashed(). Untuk menampilkan hanya data yang dihapus, gunakanProduk::onlyTrashed().
10. Testing: Memastikan Aplikasi CRUD Berfungsi dengan Baik
Testing sangat penting untuk memastikan bahwa aplikasi CRUD Anda berfungsi dengan benar dan bebas dari bug. Laravel menyediakan berbagai tools untuk mempermudah testing.
-
Membuat Feature Test: Gunakan perintah Artisan berikut untuk membuat feature test:
php artisan make:test ProdukTest -
Menulis Test: Buka file
tests/Feature/ProdukTest.php. Tulis test untuk setiap operasi CRUD. Misalnya:<?php namespace TestsFeature; use IlluminateFoundationTestingRefreshDatabase; use IlluminateFoundationTestingWithFaker; use TestsTestCase; use AppModelsProduk; class ProdukTest extends TestCase { use RefreshDatabase, WithFaker; /** @test */ public function user_can_create_a_produk() { $this->withoutExceptionHandling(); $attributes = [ 'nama' => $this->faker->sentence, 'deskripsi' => $this->faker->paragraph, 'harga' => $this->faker->randomFloat(2, 10, 100), ]; $this->post('/produks', $attributes)->assertRedirect('/produks'); $this->assertDatabaseHas('produks', $attributes); } /** @test */ public function user_can_view_a_produk() { $this->withoutExceptionHandling(); $produk = Produk::factory()->create(); $this->get('/produks/' . $produk->id) ->assertSee($produk->nama) ->assertSee($produk->deskripsi); } }Penjelasan:
use RefreshDatabase;: Meremajakan database setelah setiap test.use WithFaker;: Menggunakan Faker untuk menghasilkan data dummy.$this->withoutExceptionHandling();: Menonaktifkan exception handling untuk menampilkan error detail saat test gagal. Hapus ini saat aplikasi production.$attributes = [...]: Mendefinisikan data yang akan digunakan untuk membuat produk.$this->post('/produks', $attributes)->assertRedirect('/produks');: Mengirim request POST ke route/produksdengan data$attributesdan memastikan redirect ke/produks.$this->assertDatabaseHas('produks', $attributes);: Memastikan data$attributesada di tabelproduks.Produk::factory()->create();: Membuat instanceProdukmenggunakan factory. Pastikan Anda sudah membuat factory untuk modelProduk.
-
Menjalankan Test: Gunakan perintah Artisan berikut untuk menjalankan test:
php artisan test
11. Keamanan Tambahan: Mencegah Serangan CSRF dan XSS
Selain validasi dan otorisasi, penting untuk melindungi aplikasi CRUD dari serangan









