Salah satu hal terpenting yang perlu dipelajari dalam membuat sebuah aplikasi adalah bagaimana kita mengelola data dalam database. Oleh karena itu pada tahap ini kita akan membahas tentang mengelola data dalam tabel database yaitu Create, Read, Update dan Delete (CRUD) di Laravel 9.
Sebelum kita memulai membahas tentang Membuat CRUD di Laravel, saya asumsikan bahwa Anda telah menginstall project laravel dari awal dan juga telah melakukan konfigurasi database. Jika belum, Anda dapat mengikuti Tutorial Instalasi Laravel 9 yang telah diposting sebelumnya.
Membuat Model dan Migration
Buat Migration, Model, dan Factory dengan satu perintah seperti berikut:
php artisan make:model Product -mf
Ubah file migration database/migrations/xxxxx_create_products_table.php
menjadi seperti berikut:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('sku')->index();;
$table->string('name');
$table->decimal('price', 15, 2)->nullable();
$table->integer('stock')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
};
Ubah Model Product
(app/Models/Product) menjadi seperti berikut:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
protected $fillable = [
'sku',
'name',
'price',
'stock',
];
}
Ubah ProductFactory
(database/factories/ProductFactory) menjadi seperti berikut:
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Product>
*/
class ProductFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'sku' => Str::random(10),
'name' => fake()->name(),
'price' => fake()->randomNumber(4),
'stock' => fake()->randomNumber(2),
];
}
}
Selanjutnya, jalankan migrasi database dengan perintah:
php artisan migrate
Membuat Controller
Buat ProductController
resource dengan perintah:
php artisan make:controller ProductController -r
Perintah di atas akan membuat file app/Http/Controllers/ProductController.php
yang di dalamnya terdapat method: index
, create
, store
, show
, edit
, update
, dan destroy
.
Membuat Route
Buat routing yang akan mengarahkan ke method-method yang ada pada ProductController
:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
Route::get('products', [ProductController::class, 'index'])->name('products.index');
Route::get('products/create', [ProductController::class, 'create'])->name('products.create');
Route::post('products', [ProductController::class, 'store'])->name('products.store');
Route::get('products/{id}/edit', [ProductController::class, 'edit'])->name('products.edit');
Route::put('products/{id}', [ProductController::class, 'update'])->name('products.update');
Route::delete('products/{id}', [ProductController::class, 'destroy'])->name('products.destroy');
Membuat Validasi dengan Form Request
Disini kita membutuhkan validasi input saat store produk dan update produk. Pertama, kita akan membuat validasi dengan Form Request untuk StoreProductRequest
dengan perintah:
php artisan make:request StoreProductRequest
Update file app/Http/Requests/StoreProductRequest.php
menjadi seperti berikut:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreProductRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'sku' => ['required', 'unique:products', 'max:100'],
'name' => ['required', 'max:100'],
'price' => ['required', 'numeric', 'min:1'],
'stock' => ['required', 'numeric', 'min:0'],
];
}
}
Kemudian, kita akan membuat UpdateProductRequest
dengan perintah:
php aritsan make:request UpdateProductRequest
Update file app/Http/Requests/UpdateProductRequest.php
menjadi seperti berikut:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UpdateProductRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'sku' => [
'required',
'max:100',
Rule::unique('products')->ignore($this->id),
],
'name' => ['required', 'max:100'],
'price' => ['required', 'numeric', 'min:1'],
'stock' => ['required', 'numeric', 'min:0'],
];
}
}
Pada validasi update produk ini ada sedikit perbedaan. Yaitu saat validasi unique
untuk SKU
. Jadi pada saat update, kita perlu menambahkan ignore
terhadap id produk itu sendiri. Karena kalau tidak di ignore, maka akan mentog di validasi SKU harus unik, padahal SKU tersebut adalah milik dari produk yang sedang diedit.
Membuat Form Create Produk
Buat form sederhana untuk create produk dan simpan pada resources/views/products/create.blade.php
:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My App</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
</head>
<body>
<div id="app">
<div class="main-wrapper">
<div class="main-content">
<div class="container">
<form method="post" action="{{ route('products.store') }}">
@csrf
<div class="card mt-5">
<div class="card-header">
<h3>New Product</h3>
</div>
<div class="card-body">
@if ($errors->any())
<div class="alert alert-danger">
<div class="alert-title"><h4>Whoops!</h4></div>
There are some problems with your input.
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if (session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
<div class="mb-3">
<label class="form-label">SKU</label>
<input type="text" class="form-control" name="sku" value="{{ old('sku') }}" placeholder="#SKU">
</div>
<div class="mb-3">
<label class="form-label">Name</label>
<input type="text" class="form-control" name="name" value="{{ old('name') }}" placeholder="Name">
</div>
<div class="mb-3">
<label class="form-label">Price</label>
<input type="text" class="form-control" name="price" value="{{ old('price') }}" placeholder="Price">
</div>
<div class="mb-3">
<label class="form-label">Stock</label>
<input type="text" class="form-control" name="stock" value="{{ old('stock') }}" placeholder="Stock">
</div>
</div>
<div class="card-footer">
<button class="btn btn-primary" type="submit">Create</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
Kemudian update method create
pada ProductController
menjadi seperti berikut:
public function create()
{
return view('products.create');
}
Tampilan form create produk:
Membuat Fungsi Store Produk
Ini adalah proses menyimpan input dari form produk ke dalam tabel products
di database. Proses ini akan dihandle oleh method store
yang ada di dalam ProductController
. Pertama, kita perlu melakukan validasi input dengan StoreProductRequest
yang telah kita buat di atas. Kemudian, jika inputan tersebut lolos validasi maka kita panggil model Product
untuk menyimpan ke tabel products
. Kode program method store
akan menjadi seperti berikut:
public function store(StoreProductRequest $request)
{
if ($product = Product::create($request->validated())) {
return redirect(route('products.index'))->with('success', 'Added!');
}
}
Membuat Fungsi Read / List Produk
Untuk menampilkan data produk ini akan dihandle oleh method index
dalam ProductController
dengan kode program seperti berikut:
public function index()
{
$products = Product::all();
return view('products.index', ['products' => $products]);
}
Pertama, panggil Product::all()
untuk melakukan query mengambil semua data dalam tabel products
. Selanjutnya data tersebut akan di assign sebagai parameter pada saat render view resources/views/products/index.blade.php
.
Adapun kode program untuk index.blade.php
adalah seperti berikut:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My App</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
</head>
<body>
<div id="app">
<div class="main-wrapper">
<div class="main-content">
<div class="container">
<div class="card mt-5">
<div class="card-header">
<h3>List Product</h3>
</div>
<div class="card-body">
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if (session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
<p>
<a class="btn btn-primary" href="{{ route('products.create') }}">New Product</a>
</p>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>SKU</th>
<th>Name</th>
<th>Price</th>
<th>Stock</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@forelse ($products as $product)
<tr>
<td>{{ $product->id }}</td>
<td>{{ $product->sku }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->price }}</td>
<td>{{ $product->stock }}</td>
<td>
<a href="{{ route('products.edit', ['id' => $product->id]) }}" class="btn btn-secondary btn-sm">edit</a>
<a href="#" class="btn btn-sm btn-danger" onclick="
event.preventDefault();
if (confirm('Do you want to remove this?')) {
document.getElementById('delete-row-{{ $product->id }}').submit();
}">
delete
</a>
<form id="delete-row-{{ $product->id }}" action="{{ route('products.destroy', ['id' => $product->id]) }}" method="POST">
<input type="hidden" name="_method" value="DELETE">
@csrf
</form>
</td>
</tr>
@empty
<tr>
<td colspan="6">
No record found!
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Tampilan List Produk:
Membuat Form Edit Produk
Untuk form edit produk ini akan dihandle oleh method edit
dalam ProductController
. Kode programnya adalah seperti berikut:
public function edit($id)
{
$product = Product::findOrFail($id);
return view('products.edit', ['product' => $product]);
}
Kita perlu mencari data produk berdasar id
produk yang akan diedit. Jika ditemukan, maka data produk tersebut akan di assign sebagai parameter saat render form edit resources/views/products/edit.blade.php
. Data produk tersebut akan digunakan untuk menampilkan informasi produk pada form edit. Jadi field-field pada form edit seharusnya berisi dengan data produk yang diambil dari tabel database. Adapun kode program untuk form edit adalah sebagai berikut:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My App</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
</head>
<body>
<div id="app">
<div class="main-wrapper">
<div class="main-content">
<div class="container">
<form method="post" action="{{ route('products.update', $product->id) }}">
@method('PUT')
@csrf
<div class="card mt-5">
<div class="card-header">
<h3>Edit Product</h3>
</div>
<div class="card-body">
@if ($errors->any())
<div class="alert alert-danger">
<div class="alert-title"><h4>Whoops!</h4></div>
There are some problems with your input.
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if (session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
<div class="mb-3">
<label class="form-label">SKU</label>
<input type="text" class="form-control" name="sku" value="{{ old('sku', $product->sku) }}" placeholder="#SKU">
</div>
<div class="mb-3">
<label class="form-label">Name</label>
<input type="text" class="form-control" name="name" value="{{ old('name', $product->name) }}" placeholder="Name">
</div>
<div class="mb-3">
<label class="form-label">Price</label>
<input type="text" class="form-control" name="price" value="{{ old('price', $product->price) }}" placeholder="Price">
</div>
<div class="mb-3">
<label class="form-label">Stock</label>
<input type="text" class="form-control" name="stock" value="{{ old('stock', $product->stock) }}" placeholder="Stock">
</div>
</div>
<div class="card-footer">
<button class="btn btn-primary" type="submit">Update</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
Tampilan form edit produk:
Membuat Fungsi Update Produk
Fungsi update produk ini akan dihandle oleh method update
pada ProductController
. Kode programnya adalah seperti berikut:
public function update(UpdateProductRequest $request, $id)
{
$product = Product::findOrFail($id);
if ($product->update($request->validated())) {
return redirect(route('products.index'))->with('success', 'Updated!');
}
}
Jika berhasil melakukan update data, maka akan di-redirect ke halaman list produk dengan menampilkan success message.
Membuat Fungsi Delete Produk
Sebelum melakukan proses penghapusan data, program akan menampilkan dialog konfirmasi penghapusan ke user. Fungsi delete produk akan dihandel oleh method destroy
pada ProductController
. Kode programnya adalah seperti berikut:
public function destroy($id)
{
$product = Product::findOrFail($id);
if ($product->delete()) {
return redirect(route('products.index'))->with('success', 'Deleted!');
}
return redirect(route('products.index'))->with('error', 'Sorry, unable to delete this!');
}
Pertama akan mengecek data produk berdasarkan id yang diberikan. Jika data produk valid, baru dilakukan penghapusan. Jika sukses hapus maka akan di-redirect ke halaman list produk dengan menampilkan success message.
Tampilan konfirmasi delete produk:
Source Code CRUD Single Tabel Laravel 9
Source code lengkap tutorial ini ada di Github: https://github.com/gieart87/tutorial-laravel9/tree/feature/laravel9-crud-single-table
Tidak ada komentar:
Posting Komentar