# Membuat CRUD dengan Laravel 9 Lengkap: Tutorial Praktis untuk Pengembang Pemula
Laravel 9 adalah framework PHP yang powerful dan elegan, menjadikannya pilihan populer untuk membangun aplikasi web modern. Salah satu tugas dasar dalam pengembangan web adalah mengimplementasikan operasi CRUD (Create, Read, Update, Delete). Dalam tutorial ini, kita akan membahas secara lengkap **membuat CRUD dengan Laravel 9**, khususnya ditujukan untuk pengembang pemula. Mari kita mulai!
## 1. Persiapan Awal: Instalasi Laravel 9 dan Konfigurasi Database
Sebelum melangkah lebih jauh, pastikan Anda telah menginstal Laravel 9 dan mengkonfigurasi koneksi database. Jika belum, ikuti langkah-langkah berikut:
* **Instalasi Composer:** Laravel membutuhkan Composer untuk mengelola dependencies. Unduh dan instal Composer dari [https://getcomposer.org/](https://getcomposer.org/).
* **Instalasi Laravel:** Buka terminal atau command prompt dan jalankan perintah berikut untuk membuat project Laravel baru:
```bash
composer create-project laravel/laravel nama_project
Ganti `nama_project` dengan nama project Anda. Contoh: `composer create-project laravel/laravel crud-laravel9`
-
Konfigurasi Database: Buka file
.envdi direktori project Anda. Cari bagian database configuration dan sesuaikan dengan pengaturan database Anda (misalnya MySQL, PostgreSQL, atau SQLite). Pastikan Anda memiliki database yang sudah dibuat. Contoh konfigurasi MySQL:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nama_database_anda DB_USERNAME=username_database_anda DB_PASSWORD=password_database_andaGanti
nama_database_anda,username_database_anda, danpassword_database_andadengan kredensial database Anda. -
Migrasi Awal: Jalankan perintah berikut untuk menjalankan migrasi default Laravel:
php artisan migrate
2. Membuat Model dan Migrasi: Mempersiapkan Struktur Database untuk CRUD
Setelah Laravel terinstal dan database terkonfigurasi, langkah berikutnya adalah membuat model dan migrasi untuk entitas yang akan kita kelola menggunakan CRUD. Dalam contoh ini, kita akan membuat CRUD untuk data Product.
-
Membuat Model: Gunakan Artisan console untuk membuat model
Product:php artisan make:model ProductPerintah ini akan membuat file
Product.phpdi direktoriapp/Models. -
Membuat Migrasi: Sekarang, buat migrasi untuk tabel
products:php artisan make:migration create_products_tablePerintah ini akan membuat file migrasi baru di direktori
database/migrations. Buka file migrasi tersebut dan definisikan struktur tabelproducts. Contoh:<?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->text('description')->nullable(); $table->decimal('price', 10, 2); //Presisi 10 angka, 2 angka di belakang koma $table->integer('stock')->default(0); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('products'); } };Pada contoh di atas, kita mendefinisikan tabel
productsdengan kolom:id,name,description,price,stock,created_at, danupdated_at. Sesuaikan kolom sesuai kebutuhan Anda. -
Menjalankan Migrasi: Setelah mendefinisikan struktur tabel, jalankan migrasi untuk membuat tabel di database:
php artisan migrate
3. Membuat Controller: Logika CRUD untuk Product
Controller bertugas untuk menangani request HTTP dan berinteraksi dengan model untuk melakukan operasi CRUD. Kita akan membuat controller ProductController.
-
Membuat Controller: Gunakan Artisan console untuk membuat controller
ProductController:php artisan make:controller ProductController --resourceOpsi
--resourceakan membuat controller dengan metode-metode standar untuk operasi CRUD (index, create, store, show, edit, update, destroy). FileProductController.phpakan dibuat di direktoriapp/Http/Controllers. -
Menambahkan Kode ke Controller: Buka
ProductController.phpdan implementasikan logika untuk setiap metode CRUD. Berikut contoh implementasi:<?php namespace AppHttpControllers; use AppModelsProduct; use IlluminateHttpRequest; class ProductController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { $products = Product::all(); return view('products.index', compact('products')); } /** * Show the form for creating a new resource. * * @return IlluminateHttpResponse */ public function create() { return view('products.create'); } /** * Store a newly created resource in storage. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */ public function store(Request $request) { $request->validate([ 'name' => 'required', 'price' => 'required|numeric', 'stock' => 'required|integer', ]); Product::create($request->all()); return redirect()->route('products.index') ->with('success','Product created successfully.'); } /** * Display the specified resource. * * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function show(Product $product) { return view('products.show',compact('product')); } /** * Show the form for editing the specified resource. * * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function edit(Product $product) { return view('products.edit',compact('product')); } /** * Update the specified resource in storage. * * @param IlluminateHttpRequest $request * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function update(Request $request, Product $product) { $request->validate([ 'name' => 'required', 'price' => 'required|numeric', 'stock' => 'required|integer', ]); $product->update($request->all()); return redirect()->route('products.index') ->with('success','Product updated successfully'); } /** * Remove the specified resource from storage. * * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function destroy(Product $product) { $product->delete(); return redirect()->route('products.index') ->with('success','Product deleted successfully'); } }Penjelasan Kode:
index(): Menampilkan daftar semua produk.create(): Menampilkan form untuk membuat produk baru.store(): Menyimpan produk baru ke database. Melakukan validasi input.show(): Menampilkan detail produk tertentu.edit(): Menampilkan form untuk mengedit produk.update(): Mengupdate produk di database. Melakukan validasi input.destroy(): Menghapus produk dari database.
4. Membuat Routes: Menentukan URL untuk Setiap Aksi CRUD
Routes menghubungkan URL ke metode controller yang sesuai. Kita perlu mendefinisikan routes untuk operasi CRUD Product.
-
Mendefinisikan Routes: Buka file
routes/web.phpdan tambahkan resource route untukproducts:<?php use IlluminateSupportFacadesRoute; use AppHttpControllersProductController; /* |-------------------------------------------------------------------------- | 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('products', ProductController::class); Route::get('/', function () { return view('welcome'); });Kode
Route::resource('products', ProductController::class);secara otomatis akan membuat routes untuk semua operasi CRUD padaProductController. Anda dapat melihat daftar routes yang terdaftar dengan menjalankan perintahphp artisan route:list.
5. Membuat Views: Tampilan Antarmuka Pengguna (UI) untuk CRUD
Views bertanggung jawab untuk menampilkan data kepada pengguna. Kita perlu membuat views untuk menampilkan daftar produk, form create/edit, dan detail produk.
-
Membuat Direktori Views: Buat direktori
productsdi dalam direktoriresources/views. Direktori ini akan berisi semua views yang berhubungan denganProduct. -
Membuat File Views: Di dalam direktori
resources/views/products, buat file-file berikut:index.blade.php: Menampilkan daftar produk.create.blade.php: Menampilkan form untuk membuat produk baru.edit.blade.php: Menampilkan form untuk mengedit produk.show.blade.php: Menampilkan detail produk.
-
Contoh
index.blade.php:<!DOCTYPE html> <html> <head> <title>Products CRUD</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> @if ($message = Session::get('success')) <div class="alert alert-success"> <p>{{ $message }}</p> </div> @endif <div class="row"> <div class="col-lg-12 margin-tb"> <div class="pull-left"> <h2>Products CRUD</h2> </div> <div class="pull-right"> <a class="btn btn-success" href="{{ route('products.create') }}"> Create New Product</a> </div> </div> </div> <table class="table table-bordered"> <tr> <th>ID</th> <th>Name</th> <th>Description</th> <th>Price</th> <th>Stock</th> <th width="280px">Action</th> </tr> @foreach ($products as $product) <tr> <td>{{ $product->id }}</td> <td>{{ $product->name }}</td> <td>{{ $product->description }}</td> <td>{{ $product->price }}</td> <td>{{ $product->stock }}</td> <td> <form action="{{ route('products.destroy',$product->id) }}" method="POST"> <a class="btn btn-info" href="{{ route('products.show',$product->id) }}">Show</a> <a class="btn btn-primary" href="{{ route('products.edit',$product->id) }}">Edit</a> @csrf @method('DELETE') <button type="submit" class="btn btn-danger">Delete</button> </form> </td> </tr> @endforeach </table> </div> </body> </html>Penjelasan:
- Kode di atas menggunakan Bootstrap untuk styling. Pastikan Anda sudah menambahkan CDN Bootstrap di
<head>view Anda. - Looping data
$productsuntuk menampilkan setiap produk dalam tabel. - Menyediakan link untuk
Show,Edit, danDeletesetiap produk. - Menggunakan form dengan method
DELETEuntuk menghapus produk (sesuai dengan RESTful principles).
- Kode di atas menggunakan Bootstrap untuk styling. Pastikan Anda sudah menambahkan CDN Bootstrap di
-
Contoh
create.blade.php:<!DOCTYPE html> <html> <head> <title>Create Product</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="row"> <div class="col-lg-12 margin-tb"> <div class="pull-left"> <h2>Add New Product</h2> </div> <div class="pull-right"> <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a> </div> </div> </div> @if ($errors->any()) <div class="alert alert-danger"> <strong>Whoops!</strong> There were some problems with your input.<br><br> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <form action="{{ route('products.store') }}" method="POST"> @csrf <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Name:</strong> <input type="text" name="name" class="form-control" placeholder="Name"> </div> </div> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Description:</strong> <textarea class="form-control" style="height:150px" name="description" placeholder="Description"></textarea> </div> </div> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Price:</strong> <input type="number" step="0.01" name="price" class="form-control" placeholder="Price"> </div> </div> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Stock:</strong> <input type="number" name="stock" class="form-control" placeholder="Stock"> </div> </div> <div class="col-xs-12 col-sm-12 col-md-12 text-center"> <button type="submit" class="btn btn-primary">Submit</button> </div> </div> </form> </div> </body> </html>Penjelasan:
- Menampilkan form untuk memasukkan data produk (name, description, price, stock).
- Menangani error validasi jika input tidak valid.
- Menggunakan method
POSTuntuk mengirim data ke routeproducts.store.
-
Contoh
edit.blade.php: Mirip dengancreate.blade.php, tetapi field form diisi dengan data produk yang sudah ada. Method form diubah menjadiPUTatauPATCH. -
Contoh
show.blade.php: Menampilkan detail produk secara readonly.
Pastikan Anda menyesuaikan tampilan dan field-field form sesuai dengan kebutuhan aplikasi Anda.
6. Validasi Data: Meningkatkan Keamanan dan Integritas Data CRUD
Validasi data adalah langkah penting dalam implementasi CRUD. Laravel menyediakan cara mudah untuk memvalidasi data yang masuk sebelum disimpan ke database. Contoh validasi sudah kita lihat di store dan update method pada ProductController.
-
Menggunakan Request Validation: Anda dapat membuat class Request untuk memisahkan logika validasi dari controller. Gunakan perintah berikut untuk membuat request class:
php artisan make:request StoreProductRequestClass ini akan dibuat di direktori
app/Http/Requests. Buka fileStoreProductRequest.phpdan definisikan rules validasi pada methodrules():<?php namespace AppHttpRequests; use IlluminateFoundationHttpFormRequest; class StoreProductRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; // Atau logika otorisasi Anda } /** * Get the validation rules that apply to the request. * * @return array<string, mixed> */ public function rules() { return [ 'name' => 'required|max:255', 'description' => 'nullable', 'price' => 'required|numeric|min:0', 'stock' => 'required|integer|min:0', ]; } }Kemudian, gunakan request class ini di
storemethod padaProductController:public function store(StoreProductRequest $request) { Product::create($request->validated()); // Gunakan method validated() return redirect()->route('products.index') ->with('success','Product created successfully.'); }Dengan menggunakan Request Validation, kode controller menjadi lebih bersih dan logika validasi terpusat.
7. Keamanan CRUD: Mencegah Serangan XSS dan SQL Injection
Keamanan adalah aspek penting dalam pengembangan aplikasi web. Pastikan Anda melindungi aplikasi Anda dari serangan XSS (Cross-Site Scripting) dan SQL Injection.
- Mencegah XSS: Laravel secara otomatis melindungi aplikasi Anda dari XSS dengan melakukan escaping output secara default menggunakan syntax
{{ $variable }}di Blade templates. Hindari menggunakan{! $variable !}kecuali Anda benar-benar yakin bahwa data yang ditampilkan aman. - Mencegah SQL Injection: Laravel menggunakan Eloquent ORM, yang membantu mencegah SQL Injection dengan menggunakan parameterized queries. Hindari menggunakan raw queries kecuali benar-benar diperlukan, dan selalu gunakan parameterized queries jika menggunakan raw queries.
- Otorisasi: Pastikan hanya pengguna yang berwenang yang dapat melakukan operasi CRUD tertentu. Gunakan middleware authentication dan authorization untuk membatasi akses ke routes dan metode controller. Laravel menyediakan fitur authorization policies untuk mengelola hak akses pengguna.
8. Relasi Database: Menangani Data yang Berelasi dalam CRUD
Seringkali, data dalam aplikasi web berelasi satu sama lain. Misalnya, Product mungkin berelasi dengan Category. Laravel menyediakan cara mudah untuk mendefinisikan dan mengelola relasi database menggunakan Eloquent ORM.
-
Mendefinisikan Relasi: Di model
Product, Anda dapat mendefinisikan relasi dengan modelCategory:// app/Models/Product.php namespace AppModels; use IlluminateDatabaseEloquentFactoriesHasFactory; use IlluminateDatabaseEloquentModel; class Product extends Model { use HasFactory; // ... public function category() { return $this->belongsTo(Category::class); // Product belongs to Category } }Di model
Category:// app/Models/Category.php namespace AppModels; use IlluminateDatabaseEloquentFactoriesHasFactory; use IlluminateDatabaseEloquentModel; class Category extends Model { use HasFactory; // ... public function products() { return $this->hasMany(Product::class); // Category has many Products } } -
Menggunakan Relasi dalam CRUD: Anda dapat menggunakan relasi ini dalam controller dan views untuk menampilkan dan mengelola data yang berelasi. Misalnya, di
create.blade.php, Anda dapat menampilkan dropdown untuk memilih category:<div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Category:</strong> <select name="category_id" class="form-control"> @foreach($categories as $category) <option value="{{ $category->id }}">{{ $category->name }}</option> @endforeach </select> </div> </div>Pastikan Anda mengirimkan
category_idsaat membuat atau mengupdate product.
9. Testing CRUD: Memastikan Fungsionalitas CRUD Berjalan dengan Baik
Testing adalah bagian penting dari pengembangan perangkat lunak. Laravel menyediakan cara mudah untuk menulis dan menjalankan tests.
-
Membuat Tests: Gunakan Artisan console untuk membuat test case:
php artisan make:test ProductControllerTestFile test akan dibuat di direktori
tests/Feature. Buka file test dan tulis tests untuk setiap operasi CRUD. -
Contoh Test:
<?php namespace TestsFeature; use IlluminateFoundationTestingRefreshDatabase; use IlluminateFoundationTestingWithFaker; use TestsTestCase; use AppModelsProduct; class ProductControllerTest extends TestCase { use RefreshDatabase; // Reset database setelah setiap test use WithFaker; // Generate data palsu /** * A basic feature test example. * * @return void */ public function test_index() { $response = $this->get(route('products.index')); $response->assertStatus(200); $response->assertViewIs('products.index'); } public function test_create() { $response = $this->get(route('products.create')); $response->assertStatus(200); $response->assertViewIs('products.create'); } public function test_store() { $product = [ 'name' => $this->faker->name, 'description' => $this->faker->paragraph, 'price' => $this->faker->randomFloat(2, 10, 100), 'stock' => $this->faker->numberBetween(1, 100), ]; $response = $this->post(route('products.store'), $product); $response->assertRedirect(route('products.index')); $this->assertDatabaseHas('products', $product); } public function test_update() { $product = Product::factory()->create(); $updatedProduct = [ 'name' => $this->faker->name, 'description' => $this->faker->paragraph, 'price' => $this->faker->randomFloat(2, 10, 100), 'stock' => $this->faker->numberBetween(1, 100), ]; $response = $this->put(route('products.update', $product->id), $updatedProduct); $response->assertRedirect(route('products.index')); $this->assertDatabaseHas('products', $updatedProduct); } public function test_destroy() { $product = Product::factory()->create(); $response = $this->delete(route('products.destroy', $product->id)); $response->assertRedirect(route('products.index')); $this->assertDatabaseMissing('products', $product->toArray()); } } -
Menjalankan Tests: Jalankan tests dengan perintah:
php artisan testPastikan semua tests lulus sebelum mendeploy aplikasi Anda.
10. Optimasi Performa CRUD: Meningkatkan Kecepatan Aplikasi
Optimasi performa penting untuk memberikan pengalaman pengguna yang baik. Berikut beberapa tips untuk mengoptimasi performa CRUD di Laravel 9:
- Eager Loading: Gunakan eager loading untuk mengurangi jumlah queries database, terutama saat menampilkan data yang berelasi. Contoh:
Product::with('category')->get(); - Caching: Gunakan caching untuk menyimpan data yang sering diakses dan jarang berubah. Laravel menyediakan berbagai jenis caching, seperti file cache, database cache, dan Redis cache.
- Indexing Database: Pastikan kolom yang sering digunakan dalam queries memiliki index.
- Pagination: Gunakan pagination untuk menampilkan data dalam halaman-halaman kecil, terutama saat data yang ditampilkan sangat banyak.
- Query Optimization: Analisis queries database Anda dan optimalkan untuk mengurangi waktu eksekusi. Gunakan tools seperti Laravel Telescope untuk menganalisis queries.
- Code Optimization: Hindari looping yang tidak perlu, gunakan helper functions Laravel, dan pastikan kode Anda bersih dan efisien.
11. Debugging CRUD: Mengatasi Masalah dan Error
Debugging adalah bagian tak terpisahkan dari pengembangan. Laravel menyediakan tools yang membantu dalam debugging.
- Error Handling: Laravel memiliki error handling yang baik. Pastikan Anda mengaktifkan
APP_DEBUG=truedi file.envsaat development untuk melihat detail error. - Logging: Gunakan logging untuk mencatat error, warning, dan informasi penting lainnya. Laravel menyediakan logger yang mudah digunakan.
- Debugging Tools: Gunakan tools seperti Laravel Telescope, Xdebug, dan browser developer tools untuk membantu Anda debugging aplikasi.
- Reading Error Messages: Pahami pesan error yang ditampilkan dan gunakan informasi tersebut untuk menemukan penyebab masalah.
- Google and Stack Overflow: Jangan ragu untuk mencari solusi di Google dan Stack Overflow. Banyak pengembang lain yang mungkin mengalami masalah yang sama dan telah menemukan solusinya.
Dengan mengikuti tutorial ini, Anda akan memiliki pemahaman yang kuat tentang membuat CRUD dengan Laravel 9. Ingatlah untuk selalu menguji kode Anda, menjaga keamanan, dan mengoptimalkan performa aplikasi Anda. Selamat mencoba dan semoga berhasil!

