Laravel, framework PHP yang populer, menawarkan cara yang elegan dan efisien untuk membangun aplikasi web. Salah satu tugas fundamental dalam pengembangan web adalah implementasi CRUD (Create, Read, Update, Delete). Artikel ini adalah panduan lengkap dan praktis tentang cara membuat CRUD dengan Laravel 9, mulai dari instalasi hingga validasi data. Yuk, kita mulai!
1. Persiapan: Instalasi Laravel 9 dan Konfigurasi Database
Sebelum kita menyelam lebih dalam, pastikan kamu sudah memiliki Laravel 9 terinstall. Jika belum, ikuti langkah-langkah berikut:
1.1. Memastikan Persyaratan Sistem Terpenuhi:
- PHP: Minimal PHP 8.0.
- Composer: Dependency Manager untuk PHP.
- Database: MySQL, PostgreSQL, SQLite, atau SQL Server.
- Web Server: Apache atau Nginx (dengan konfigurasi yang benar).
1.2. Menginstall Laravel 9 dengan Composer:
Buka terminal atau command prompt dan jalankan perintah berikut:
composer create-project laravel/laravel:^9.0 nama-projek-crud
Ganti nama-projek-crud
dengan nama projek yang kamu inginkan.
1.3. Konfigurasi Database (MySQL):
Setelah Laravel terinstall, kita perlu mengkonfigurasi koneksi ke database. Buka file .env
di direktori projek dan cari bagian yang berhubungan dengan database:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nama_database
DB_USERNAME=nama_pengguna
DB_PASSWORD=password_database
DB_CONNECTION
: Tentukan jenis database yang digunakan (dalam contoh ini,mysql
).DB_HOST
: Alamat server database (biasanya127.0.0.1
ataulocalhost
).DB_PORT
: Port yang digunakan oleh database (default MySQL adalah3306
).DB_DATABASE
: Nama database yang akan digunakan. Buat database ini di MySQL terlebih dahulu.DB_USERNAME
: Nama pengguna database.DB_PASSWORD
: Kata sandi database.
Pastikan data konfigurasi ini sesuai dengan pengaturan database kamu. Simpan perubahan di file .env
.
1.4. Migrasi Database Awal:
Laravel menyediakan fitur migrations untuk membuat dan memodifikasi struktur database. Jalankan perintah berikut untuk menjalankan migrations bawaan Laravel:
php artisan migrate
Perintah ini akan membuat tabel users
, password_resets
, dan failed_jobs
di database kamu.
2. Membuat Model dan Migrasi: Representasi Data di Laravel
Selanjutnya, kita akan membuat model dan migrasi untuk merepresentasikan data yang akan kita kelola dengan CRUD. Misalkan kita ingin membuat CRUD untuk mengelola data “Artikel”.
2.1. Membuat Model Artikel:
Jalankan perintah berikut untuk membuat model “Artikel”:
php artisan make:model Artikel -m
Perintah ini akan membuat dua file:
app/Models/Artikel.php
: File model Artikel.database/migrations/xxxx_xx_xx_xxxxxx_create_artikels_table.php
: File migrasi untuk membuat tabelartikels
.
2.2. Mendefinisikan Struktur Tabel Artikel di Migrasi:
Buka file migrasi (yang ada di database/migrations
) dan modifikasi method up()
untuk mendefinisikan struktur tabel artikels
. Contoh:
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('artikels', function (Blueprint $table) {
$table->id();
$table->string('judul');
$table->text('isi');
$table->string('penulis');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('artikels');
}
};
Penjelasan:
$table->id()
: Membuat kolomid
sebagai primary key auto-increment.$table->string('judul')
: Membuat kolomjudul
dengan tipe datastring
.$table->text('isi')
: Membuat kolomisi
dengan tipe datatext
(untuk konten yang lebih panjang).$table->string('penulis')
: Membuat kolompenulis
dengan tipe datastring
.$table->timestamps()
: Membuat kolomcreated_at
danupdated_at
untuk mencatat waktu pembuatan dan pembaruan data.
2.3. Menjalankan Migrasi:
Setelah mendefinisikan struktur tabel, jalankan migrasi untuk membuat tabel artikels
di database:
php artisan migrate
3. Membuat Controller: Logika Aplikasi dan Handler Request
Controller berperan sebagai perantara antara model dan view. Controller bertanggung jawab untuk menerima request, memproses data, dan mengirimkan respons.
3.1. Membuat Controller Artikel:
Gunakan perintah berikut untuk membuat controller “ArtikelController”:
php artisan make:controller ArtikelController --resource
Opsi --resource
secara otomatis akan membuat method-method dasar CRUD (index, create, store, show, edit, update, destroy) di controller.
3.2. Implementasi Method CRUD di Controller:
Buka file app/Http/Controllers/ArtikelController.php
dan implementasikan logic untuk setiap method CRUD:
<?php
namespace AppHttpControllers;
use AppModelsArtikel;
use IlluminateHttpRequest;
class ArtikelController extends Controller
{
/**
* Display a listing of the resource.
*
* @return IlluminateHttpResponse
*/
public function index()
{
$artikels = Artikel::all();
return view('artikels.index', compact('artikels'));
}
/**
* Show the form for creating a new resource.
*
* @return IlluminateHttpResponse
*/
public function create()
{
return view('artikels.create');
}
/**
* Store a newly created resource in storage.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function store(Request $request)
{
$request->validate([
'judul' => 'required',
'isi' => 'required',
'penulis' => 'required',
]);
Artikel::create($request->all());
return redirect()->route('artikels.index')
->with('success','Artikel berhasil ditambahkan.');
}
/**
* Display the specified resource.
*
* @param AppModelsArtikel $artikel
* @return IlluminateHttpResponse
*/
public function show(Artikel $artikel)
{
return view('artikels.show',compact('artikel'));
}
/**
* Show the form for editing the specified resource.
*
* @param AppModelsArtikel $artikel
* @return IlluminateHttpResponse
*/
public function edit(Artikel $artikel)
{
return view('artikels.edit',compact('artikel'));
}
/**
* Update the specified resource in storage.
*
* @param IlluminateHttpRequest $request
* @param AppModelsArtikel $artikel
* @return IlluminateHttpResponse
*/
public function update(Request $request, Artikel $artikel)
{
$request->validate([
'judul' => 'required',
'isi' => 'required',
'penulis' => 'required',
]);
$artikel->update($request->all());
return redirect()->route('artikels.index')
->with('success','Artikel berhasil diperbarui');
}
/**
* Remove the specified resource from storage.
*
* @param AppModelsArtikel $artikel
* @return IlluminateHttpResponse
*/
public function destroy(Artikel $artikel)
{
$artikel->delete();
return redirect()->route('artikels.index')
->with('success','Artikel berhasil dihapus');
}
}
Penjelasan:
index()
: Mengambil semua data artikel dari database dan mengirimkannya ke viewartikels.index
.create()
: Menampilkan form untuk membuat artikel baru (viewartikels.create
).store()
: Menerima data dari form, melakukan validasi, menyimpan data ke database, dan mengarahkan kembali ke halamanartikels.index
. Perhatikan penggunaan$request->validate()
untuk validasi data.show(Artikel $artikel)
: Menampilkan detail artikel (viewartikels.show
). Perhatikan type hintingArtikel $artikel
. Laravel secara otomatis mencari data artikel berdasarkan ID yang diberikan di route.edit(Artikel $artikel)
: Menampilkan form untuk mengedit artikel (viewartikels.edit
).update(Request $request, Artikel $artikel)
: Menerima data dari form, melakukan validasi, memperbarui data di database, dan mengarahkan kembali ke halamanartikels.index
.destroy(Artikel $artikel)
: Menghapus artikel dari database dan mengarahkan kembali ke halamanartikels.index
.
4. Membuat View (Tampilan): Antarmuka Pengguna CRUD
View adalah tampilan antarmuka pengguna yang ditampilkan kepada pengguna. Kita akan membuat beberapa view untuk setiap operasi CRUD.
4.1. Struktur Direktori View:
Buat direktori artikels
di dalam direktori resources/views
. Di dalam direktori artikels
, buat file-file berikut:
index.blade.php
: Menampilkan daftar artikel.create.blade.php
: Form untuk membuat artikel baru.edit.blade.php
: Form untuk mengedit artikel.show.blade.php
: Menampilkan detail artikel.
4.2. Contoh Implementasi index.blade.php
:
<!-- resources/views/artikels/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>CRUD Artikel</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Daftar Artikel</h1>
<a class="btn btn-success" href="{{ route('artikels.create') }}"> Buat Artikel Baru</a>
@if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
@endif
<table class="table table-bordered">
<tr>
<th>No</th>
<th>Judul</th>
<th>Isi</th>
<th>Penulis</th>
<th width="280px">Action</th>
</tr>
@foreach ($artikels as $artikel)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $artikel->judul }}</td>
<td>{{ substr($artikel->isi, 0, 100) }}...</td>
<td>{{ $artikel->penulis }}</td>
<td>
<form action="{{ route('artikels.destroy',$artikel->id) }}" method="POST">
<a class="btn btn-info" href="{{ route('artikels.show',$artikel->id) }}">Show</a>
<a class="btn btn-primary" href="{{ route('artikels.edit',$artikel->id) }}">Edit</a>
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</table>
{!! $artikels->links() !!}
</div>
</body>
</html>
4.3. Contoh Implementasi create.blade.php
:
<!-- resources/views/artikels/create.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Buat Artikel Baru</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Buat Artikel Baru</h1>
@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('artikels.store') }}" method="POST">
@csrf
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Judul:</strong>
<input type="text" name="judul" class="form-control" placeholder="Judul">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Isi:</strong>
<textarea class="form-control" style="height:150px" name="isi" placeholder="Isi"></textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Penulis:</strong>
<input type="text" name="penulis" class="form-control" placeholder="Penulis">
</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>
4.4. Implementasikan edit.blade.php
dan show.blade.php
:
Buat implementasi yang serupa untuk edit.blade.php
dan show.blade.php
, menyesuaikan dengan kebutuhan tampilan masing-masing. Perhatikan penggunaan @csrf
dan @method('PUT')
pada form edit untuk keamanan dan HTTP method yang benar.
5. Mendefinisikan Routes: Menghubungkan URL ke Controller
Routes mendefinisikan bagaimana URL (Uniform Resource Locator) diakses dan dipetakan ke method controller yang sesuai.
5.1. Menggunakan Resource Routing:
Buka file routes/web.php
dan tambahkan route resource untuk artikel:
<?php
use IlluminateSupportFacadesRoute;
use AppHttpControllersArtikelController;
/*
|--------------------------------------------------------------------------
| 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('artikels', ArtikelController::class);
Route::get('/', function () {
return view('welcome');
});
Route::resource('artikels', ArtikelController::class)
secara otomatis akan membuat route untuk semua operasi CRUD (index, create, store, show, edit, update, destroy) yang mengarah ke method controller yang sesuai. Ini cara yang sangat efisien dan convention over configuration.
6. Validasi Data dengan Laravel: Memastikan Kualitas Data
Validasi data sangat penting untuk memastikan data yang disimpan di database valid dan konsisten. Laravel menyediakan fitur validasi yang kuat dan mudah digunakan.
6.1. Menerapkan Validasi di Controller:
Kita sudah melihat contoh validasi di method store()
dan update()
di ArtikelController.php
. Kita menggunakan $request->validate()
untuk mendefinisikan aturan validasi.
public function store(Request $request)
{
$request->validate([
'judul' => 'required',
'isi' => 'required',
'penulis' => 'required',
]);
Artikel::create($request->all());
return redirect()->route('artikels.index')
->with('success','Artikel berhasil ditambahkan.');
}
6.2. Aturan Validasi yang Umum:
Beberapa aturan validasi yang umum digunakan:
required
: Field wajib diisi.string
: Field harus berupa string.integer
: Field harus berupa integer.email
: Field harus berupa alamat email yang valid.unique
: Field harus unik dalam tabel database tertentu.max:255
: Panjang maksimum field adalah 255 karakter.min:3
: Panjang minimum field adalah 3 karakter.
Kamu bisa menemukan daftar lengkap aturan validasi di dokumentasi Laravel: https://laravel.com/docs/9.x/validation
6.3. Menampilkan Pesan Error Validasi:
Di view (terutama di form create.blade.php
dan edit.blade.php
), kita menampilkan pesan error validasi menggunakan $errors
:
@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
7. Tampilan yang Lebih Menarik dengan Templating (Blade)
Blade adalah templating engine bawaan Laravel yang memungkinkan kita membuat tampilan yang dinamis dan mudah dikelola. Kita sudah menggunakan Blade di contoh-contoh view sebelumnya.
7.1. Sintaks Blade yang Penting:
{{ $variable }}
: Menampilkan nilai variable (secara otomatis melakukan escaping HTML untuk mencegah XSS).{!! $variable !!}
: Menampilkan nilai variable tanpa escaping HTML (hati-hati, gunakan hanya jika kamu yakin kontennya aman).@if (kondisi)
…@endif
: Pernyataan kondisional.@foreach ($array as $item)
…@endforeach
: Looping.@extends('layouts.app')
: Mewarisi layout dari filelayouts/app.blade.php
.@section('content')
…@endsection
: Mendefinisikan section yang akan diisi di layout.
7.2. Membuat Layout:
Membuat layout (misalnya resources/views/layouts/app.blade.php
) memungkinkan kita untuk menghindari pengulangan kode di setiap view. Layout berisi struktur dasar HTML dan section-section yang bisa diisi oleh view lain.
<!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Aplikasi CRUD Artikel</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
@yield('content')
</div>
</body>
</html>
7.3. Menggunakan Layout:
Di view lain (misalnya artikels/index.blade.php
), kita bisa menggunakan layout:
<!-- resources/views/artikels/index.blade.php -->
@extends('layouts.app')
@section('content')
<h1>Daftar Artikel</h1>
...
@endsection
8. Relasi Database: Menghubungkan Tabel-Tabel
Seringkali, data yang kita kelola memiliki relasi antara tabel-tabel. Misalnya, setiap artikel mungkin memiliki seorang penulis. Kita bisa mendefinisikan relasi ini di model.
8.1. Contoh Relasi One-to-Many:
Jika kita memiliki tabel users
(yang sudah ada secara default di Laravel) dan setiap artikel dimiliki oleh seorang user, kita bisa mendefinisikan relasi one-to-many
di model Artikel.php
:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Artikel extends Model
{
use HasFactory;
protected $fillable = [
'judul',
'isi',
'penulis',
'user_id', // Foreign key ke tabel users
];
public function user()
{
return $this->belongsTo(User::class);
}
}
Di model User.php
, kita definisikan relasi kebalikannya:
<?php
namespace AppModels;
use IlluminateContractsAuthMustVerifyEmail;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use LaravelSanctumHasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function artikels()
{
return $this->hasMany(Artikel::class);
}
}
8.2. Menggunakan Relasi di Controller dan View:
Setelah mendefinisikan relasi, kita bisa menggunakannya di controller dan view untuk mengakses data yang berhubungan. Misalnya, untuk menampilkan nama user yang membuat artikel di artikels/show.blade.php
:
<p>Penulis: {{ $artikel->user->name }}</p>
9. Autentikasi dan Otorisasi: Keamanan Aplikasi CRUD
Keamanan sangat penting dalam aplikasi CRUD. Laravel menyediakan fitur autentikasi dan otorisasi yang mudah digunakan.
9.1. Implementasi Autentikasi Bawaan Laravel:
Laravel menyediakan fitur autentikasi yang bisa di-scaffold dengan satu perintah:
composer require laravel/ui
php artisan ui:auth
npm install && npm run dev
Perintah ini akan membuat route, controller, dan view untuk login, register, dan reset password. Jangan lupa jalankan php artisan migrate
setelahnya.
9.2. Menerapkan Middleware auth
:
Kita bisa menggunakan middleware auth
untuk melindungi route yang hanya bisa diakses oleh pengguna yang sudah login. Di routes/web.php
:
Route::resource('artikels', ArtikelController::class)->middleware('auth');
Ini akan memastikan bahwa hanya pengguna yang sudah login yang bisa mengakses route-route CRUD artikel.
9.3. Otorisasi:
Otorisasi menentukan hak akses pengguna terhadap sumber daya tertentu. Laravel menyediakan fitur Policies untuk mengimplementasikan otorisasi.
10. Testing: Memastikan CRUD Berfungsi dengan Baik
Testing sangat penting untuk memastikan bahwa aplikasi CRUD kita berfungsi dengan baik dan bebas dari bug. Laravel menyediakan dukungan yang baik untuk testing.
10.1. Membuat Test:
Gunakan perintah berikut untuk membuat test untuk ArtikelController:
php artisan make:test ArtikelControllerTest
10.2. Menulis Test:
Buka file tests/Feature/ArtikelControllerTest.php
dan tulis test untuk setiap operasi CRUD. Misalnya, untuk menguji method store()
:
<?php
namespace TestsFeature;
use IlluminateFoundationTestingRefreshDatabase;
use IlluminateFoundationTestingWithFaker;
use TestsTestCase;
use AppModelsUser;
use AppModelsArtikel;
class ArtikelControllerTest extends TestCase
{
use RefreshDatabase;
public function test_store_artikel()
{
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->post('/artikels', [
'judul' => 'Judul Artikel Test',
'isi' => 'Isi Artikel Test',
'penulis' => 'Penulis Artikel Test',
]);
$response->assertRedirect('/artikels');
$this->assertDatabaseHas('artikels', [
'judul' => 'Judul Artikel Test',
]);
}
}
10.3. Menjalankan Test:
Jalankan semua test dengan perintah:
php artisan test
11. Deploying ke Production: Meluncurkan Aplikasi CRUD
Setelah semua fitur CRUD diimplementasikan, diuji, dan dipastikan berjalan dengan baik, saatnya untuk mendeploy aplikasi ke production.
11.1. Konfigurasi Production:
- Pastikan konfigurasi database di file
.env
sudah sesuai dengan database production. - Set
APP_ENV=production
di file.env
. - Jalankan
php artisan config:cache
untuk mengoptimalkan konfigurasi. - Jalankan
php artisan route:cache
untuk mengoptimalkan route. - Set
APP_DEBUG=false
di file.env
.
11.2. Migrasi Database di Production:
Jalankan migrations di database production:
php artisan migrate --force
Opsi --force
diperlukan di environment production untuk mengkonfirmasi bahwa kamu yakin ingin menjalankan migrations.
11.3. Mengoptimalkan Asset:
Compile asset (CSS dan JavaScript) untuk production:
npm run production
11.4. Menggunakan Supervisor (untuk Queue):
Jika aplikasi kamu menggunakan queue, gunakan Supervisor untuk memastikan queue worker berjalan terus menerus.
12. Tips SEO untuk Aplikasi CRUD Laravel 9
Meskipun CRUD lebih fokus pada fungsi aplikasi, tetap penting memperhatikan SEO:
- URL yang Bersih dan Deskriptif: Gunakan slug yang deskriptif untuk URL (misalnya
/artikels/cara-membuat-crud-laravel-9
). - Meta Deskripsi yang Relevan: Tambahkan meta deskripsi di setiap halaman yang menjelaskan konten halaman tersebut.
- Judul Halaman yang Unik: Setiap halaman harus memiliki judul yang unik dan relevan dengan kontennya.
- Alt Text untuk Gambar: Jika menggunakan gambar, tambahkan alt text yang deskriptif.
- Mobile-Friendly: Pastikan tampilan aplikasi responsif dan mudah digunakan di perangkat mobile.
- Kecepatan Loading Halaman: Optimalkan kecepatan loading halaman dengan mengompres gambar, menggunakan caching, dan CDN.
Dengan mengikuti panduan lengkap dan praktis ini, kamu sekarang memiliki pemahaman yang kuat tentang cara membuat CRUD dengan Laravel 9. Selamat mencoba dan semoga sukses dengan projekmu! Jangan ragu untuk kembali ke artikel ini jika kamu menemukan kendala. Ingat, kunci sukses adalah praktik dan eksplorasi!