Setelah beberapa tahun menggunakan framework yang berbeda, akhirnya saya mulai fokus belajar laravel. Bisa dilihat di arsip blog ini, saya belajar laravel 8 mulai pada bulan September 2021 lalu. Setelah beberapa bulan belajar dan mulai project baru, masuk ke bulan februari tahun 2022 rilis laravel versi selanjutnya, dan tahun 2023 sekarang rilis laravel versi terbaru yaitu laravel 10. Untuk yang baru belajar tentu ini menjadi hal yang saya pikirkan, apakah harus tetap fokus mempelajari laravel 8 atau melompat ke laravel versi terbaru? Apakah ada perbedaan antara Laravel 10 dengan Laravel 8? Bagaimana dengan sintaksis atau struktur kodenya? Banyak hal yang menjadi pertanyaan, terutama untuk yang baru belajar framework Laravel seperti saya.
Untuk menjawab pertanyaan-pertanyaan tersebut, akhirnya saya mulai mencoba bereksperimen menggunakan Laravel 10 dan mencoba membuat aplikasi dengan fitur CRUD. Supaya agak berbeda dengan catatan belajar sebelumnya tentang crud laravel 8, saya juga coba untuk menggunakan Tailwindcss untuk user interface. Selain itu ada beberapa hal yang ingin saya coba setelah beberapa waktu diskusi tentang laravel. Kamu tertarik belajar juga? Kalau begitu yuk kita sama-sama coba!
Sebelum kita mulai, kita mesti cek dulu versi PHP yang terinstall. Karena Laravel 10 ini memerlukan minimal PHP versi 8.1 Kita buka terminal terlebih dahulu, lalu kita run command ini untuk cek versi PHP.
php -v
Output:
PHP 8.1.6 (cli) (built: May 12 2022 23:30:39) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.6, Copyright (c) Zend Technologies
with Xdebug v3.1.4, Copyright (c) 2002-2022, by Derick Rethans
with Zend OPcache v8.1.6, Copyright (c), by Zend Technologies
PHP yang terinstall saat tutorial ini dibuat adalah PHP 8.1.6. Ya, requirement pertama untuk Laravel 10 sudah terpenuhi. Sebelum kita mulai development, kita perlu pastikan minimum versi PHP dan juga ekstensi yang diperlukan:
Pastikan semuanya sudah terinstall. Kita bisa gunakan function phpinfo()
untuk mengecek apakah ekstensi yang diperlukan sudah terinstall.
Setelah semua requirement-nya terpenuhi, kita bisa langsung coba buat project CRUD Laravel 10 dan Tailwind css.
Pada percobaan kali ini kita akan mencoba membuat project sederhana seperti pada tutorial crud Laravel versi sebelumnya yaitu project blog. Kita akan coba beberapa hal yaitu:
php artisan
Langkah pertama adalah install Laravel 10 untuk project crud kita. Buka terminal lalu run composer
untuk menginstall Laravel 10.
composer create-project laravel/laravel:^10.0 blog
Setelah Laravel 10 sudah terinstall, masuk ke direktori project.
cd blog
Setelah itu kita bisa cuma run project kita menggunakan artisan
command.
php artisan serve
Kemudian buka url http://127.0.0.1:8000/
di browser. Setelah project kita buka di browser, kita bisa lihat halaman default framework laravel dan kita juga bisa lihat keterangan versi laravel dan versi PHP yang kita pakai di posisi kanan bawah, misalnya Laravel v10.0.3 (PHP v8.1.6)
.
Setelah Laravel 10 berhasil kita install dan coba kita run di langkah sebelumnya, sekarang kita akan atur konfigurasi database. Buka file .env
, lalu sesuaikan dengan credentials mysql dan nama database.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_blog
DB_USERNAME=admin
DB_PASSWORD=password
Sebagai contoh, nama database untuk project kita adalah db_blog
, sedangkan untuk credentials mysql, usernamenya admin
dan passwordnya password
.
Setelah selesai save kembali file .env
.
Selanjutnya kita buat database baru dengan nama db_blog
(atau nama database apapun yang kamu setting di file .env
). Kita bisa buat database baru melalui phpmyadmin
atau command sql. Buka terminal lalu kita login ke mysql.
mysql -u admin -p
Setelah kita masukan passwordnya, akan tampil output seperti di bawah ini.
$ mysql -u admin -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 85
Server version: 5.7.37 Homebrew
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Selanjutnya kita buat database baru menggunakan command.
CREATE DATABASE db_blog;
Output:
mysql> CREATE DATABASE db_blog;
Query OK, 1 row affected (0.00 sec)
Setelah database kita buat, selanjutnya keluar dari cli mysql.
exit;
Pada tahapan ini kita akan membuat file model sekaligus file migration menggunakan artisan
command. Karena project kita tentang blog, kita akan buat model untuk post dengan nama Post
. Buka kembali terminal, lalu kita run command untuk membuat model dan migration.
php artisan make:model Post -m
Output:
INFO Model **[app/Models/Post.php]** created successfully.
INFO Migration **[database/migrations/2023_02_20_130437_create_posts_table.php]** created successfully.
Pada output yang ditampilkan, kita bisa lihat file model dan file migration berhasil dibuat. Dengan menggunakan opsi -m
pada artisan
command make:model
, kita bisa langsung buat file migration sesuai dengan model-nya.
Selanjutnya kita buka file model yang baru saja dibuat. yaitu app/Models/Post.php
, lalu kita definisikan properties $fillable
untuk mengatur mass assignment
atau data apa saja yang diperbolehkan ketika ada proses insert atau update.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title', 'content', 'slug', 'status'
];
}
Pada baris kode di atas, hanya title
, content
, slug
, dan status
yang bisa ditambahkan ke table posts
pada saat proses insert ataupun update.
Selanjutnya kita buat table posts
menggunakan file migration yang sebelumnya berhasil kita generate menggunakan artisan command
. Buka file database/migrations/yyyy_mm_dd_xxxxxx_create_posts_table.php
, lalu kita tambahkan kolom untuk table posts
sesuai dengan yang dengan yang sudah kita atur pada model Post
.
<?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('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->string('slug');
$table->smallInteger('status');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
Setelah itu kita run migration.
php artisan migrate
Output:
INFO Preparing database.
Creating migration table ......................................... 25ms **DONE**
INFO Running migrations.
2014_10_12_000000_create_users_table ............................. 23ms **DONE**
2014_10_12_100000_create_password_reset_tokens_table ............. 21ms **DONE**
2019_08_19_000000_create_failed_jobs_table ....................... 15ms **DONE**
2019_12_14_000001_create_personal_access_tokens_table ............ 24ms **DONE**
2023_02_20_130437_create_posts_table .............................. 9ms **DONE**
Ya, table posts
(dan table lainnya) berhasil dibuat setelah kita run migration.
Fitur pertama yang akan tambahkan adalah fitur untuk menampilkan data post
pada project kita. Pertama kita buat terlebih dahulu file controller menggunakan artisan command.
php artisan make:controller PostController --model=Post --resource
Output:
INFO Controller **[app/Http/Controllers/PostController.php]** created successfully.
Seperti yang sudah disebutkan pada Overview Project, kita coba gunakan opsi --model
dan resource
untuk generate PostController
.
--model=Post
kita tambahkan karena kita akan coba menggunakan route model binding
. Jadi nanti controller hasil generate akan memiliki method dengan type hint instance sebuah model.--resource
kita tambahkan untuk generate controller yang menangani crud. Jadi ketika controller di-generate, controller akan memiliki method yang menangani crud.Supaya lebih jelas, sekarang kita buka file app/Http/Controllers/PostController.php
dan kita bisa lihat ada beberapa method yang sudah di-generate, seperti method index()
, create()
,store()
,show()
,edit()
, update()
, dan destroy()
.
Baik kita lanjutkan.
Sekarang kita tambahkan baris kode pada method index()
untuk menampilkan halaman daftar post.
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
$posts = Post::orderBy('id', 'DESC')->paginate(10);
return view('posts.index', compact('posts'));
}
}
Method index()
ini menangani untuk menampilkan halaman daftar post. Pada baris kode di atas, terdapat $posts
yang berisi data post yang akan dipassing dan ditampilkan di view posts.index
.
Langkah berikutnya adalah membuat file view yang akan kita pakai untuk menampilkan data dari variable $posts
, yaitu posts/index.blade.php
. Kita buat dulu folder baru dengan nama posts
, lalu di dalam folder posts
kita buat file index.blade.php
. Di dalam file index.blade.php
kita tambahkan baris kode berikut ini.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Post List - Tutorial CRUD Laravel 10 @ qadrlabs.com</title>
</head>
<body>
<div class="container mx-auto mt-10 mb-10 px-10">
<div class="grid grid-cols-8 gap-4 mb-4 p-5">
<div class="col-span-4 mt-2">
<h1 class="text-3xl font-bold">
DAFTAR POST
</h1>
</div>
<div class="col-span-4">
<div class="flex justify-end">
<a href="{{ route('post.create') }}"
class="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded-full shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out"
id="add-post-btn">+ Create New Post</a>
</div>
</div>
</div>
<div class="bg-white p-5 rounded shadow-sm">
<!-- Notifikasi menggunakan flash session data -->
@if (session('success'))
<div class="p-3 rounded bg-green-500 text-green-100 mb-4">
{{ session('success') }}
</div>
@endif
<table class="min-w-full table-auto border">
<thead class="border-b">
<tr>
<th scope="col" class="text-sm font-medium text-gray-900 px-6 py-4 text-left">Title</th>
<th scope="col" class="text-sm font-medium text-gray-900 px-6 py-4 text-center">Status</th>
<th scope="col" class="text-sm font-medium text-gray-900 px-6 py-4 text-center">Create At</th>
<th scope="col" class="text-sm font-medium text-gray-900 px-6 py-4 text-center">Action</th>
</tr>
</thead>
<tbody>
@forelse ($posts as $post)
<tr class="border-b">
<td class="text-sm text-gray-900 font-light px-6 py-4 whitespace-nowrap">{{ $post->title }}</td>
<td class="text-sm text-gray-900 font-light px-6 py-4 whitespace-nowrap text-center">{{ $post->status == 0 ? 'Draft':'Publish' }}</td>
<td class="text-sm text-gray-900 font-light px-6 py-4 whitespace-nowrap text-center">{{ $post->created_at->format('d-m-Y') }}</td>
<td class="text-sm text-gray-900 font-light px-6 py-4 whitespace-nowrap text-center">
<form onsubmit="return confirm('Apakah Anda Yakin ?');"
action="{{ route('post.destroy', $post->id) }}" method="POST">
@csrf
@method('DELETE')
<a href="{{ route('post.edit', $post->id) }}" id="{{ $post->id }}-edit-btn"
class="inline-block px-6 py-2.5 bg-blue-400 text-white font-medium text-xs leading-tight uppercase rounded-full shadow-md hover:bg-blue-500 hover:shadow-lg focus:bg-blue-500 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-600 active:shadow-lg transition duration-150 ease-in-out">Edit</a>
<button type="submit"
class="inline-block px-6 py-2.5 bg-red-600 text-white font-medium text-xs leading-tight uppercase rounded-full shadow-md hover:bg-red-700 hover:shadow-lg focus:bg-red-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-red-800 active:shadow-lg transition duration-150 ease-in-out"
id="{{ $post->id }}-delete-btn">Delete
</button>
</form>
</td>
</tr>
@empty
<tr>
<td class="text-center text-sm text-gray-900 px-6 py-4 whitespace-nowrap" colspan="4">Data post tidak tersedia</td>
</tr>
@endforelse
</tbody>
</table>
<div class="mt-3">
{{ $posts->links() }}
</div>
</div>
</div>
<script src="https://cdn.tailwindcss.com/?plugins=forms"></script>
</body>
</html>
Pada baris kode di atas, terdapat variable $posts
yang sebelumnya kita passing dari controller pada method index()
menggunakan function view()
. Selanjutnya kita looping $posts
menggunakan blade directive, yaitu @forelse
. Selain @forelse
, kita bisa lihat ada blade directive @if
untuk pengecekan notifikasi.
Untuk tampilan atau user interface, kita coba memakai tailwindcss. Bisa kita lihat terdapat script untuk load tailwindcss sebelum tag </body>
.
<script src="https://cdn.tailwindcss.com/?plugins=forms"></script>
Karena belum menambahkan route, kita belum bisa run project untuk melihat halaman daftar post. Jadi sekarang kita tambahkan atau register route baru di file routes/web.php
.
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| 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::get('/', function () {
return view('welcome');
});
Route::resource('post', \App\Http\Controllers\PostController::class); // tambahkan ini
Route pada baris kode di atas, sudah menangani route untuk menampilkan data, menambahkan data, memperbaharui data dan menghapus data. Untuk mengecek route yang sudah kita register, kita bisa gunakan command.
php artisan route:list
Output:
GET|HEAD / ..........................................................
POST _ignition/execute-solution ignition.executeSolution › Spati…
GET|HEAD _ignition/health-check ignition.healthCheck › Spatie\Larave…
POST _ignition/update-config ignition.updateConfig › Spatie\Lara…
GET|HEAD api/user ...................................................
GET|HEAD post ..................... post.index › PostController@index
POST post ..................... post.store › PostController@store
GET|HEAD post/create ............ post.create › PostController@create
GET|HEAD post/{post} ................ post.show › PostController@show
PUT|PATCH post/{post} ............ post.update › PostController@update
DELETE post/{post} .......... post.destroy › PostController@destroy
GET|HEAD post/{post}/edit ........... post.edit › PostController@edit
GET|HEAD sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum …
Setelah route kita register, kita bisa akses halaman daftar post dengan membuka url http://127.0.0.1:8000/post
di browser.
Tahapan selanjutnya adalah menambahkan fitur untuk tambah data di project kita. Buka kembali file controller PostController.php
, lalu kita tambahkan baris kode pada method create()
untuk menampilkan form menambah data baru.
<?php
// ... baris kode sebelumnya
class PostController extends Controller
{
// ... baris kode sebelumnya
public function create()
{
return view('posts.create');
}
}
Ya, method ini menangani untuk proses menampilkan halaman untuk menambahkan data, dengan me-return function view()
. Selanjutnya kita buat file view baru, sesuai yang ada pada method view, yaitu file create.blade.php
di dalam folder posts
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Create New Post - Tutorial CRUD Laravel 10 @ qadrlabs.com</title>
</head>
<body>
<div class="container mx-auto mt-10 mb-10 px-10">
<div class="grid grid-cols-8 gap-4 p-5">
<div class="col-span-4 mt-2">
<h1 class="text-3xl font-bold">
CREATE NEW POST
</h1>
</div>
<div class="col-span-4">
</div>
</div>
<div class="bg-white p-5 rounded shadow-sm">
<form action="{{ route('post.store') }}" method="POST">
@csrf
<div class="mb-5">
<label for="title">Title</label>
<input type="text" class="
form-control
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded-full
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none
" name="title" value="{{ old('title') }}" required>
<!-- error message untuk title -->
@error('title')
<div class="bg-red-400 p-2 shadow-sm rounded mt-2">
{{ $message }}
</div>
@enderror
</div>
<div class="mb-5">
<label for="status">Publish Status</label>
<select name="status" class="form-select appearance-none
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding bg-no-repeat
border border-solid border-gray-300
rounded-full
transition
ease-in-out
m-0 focus:text-gray-700 focus:bg-white
focus:border-blue-600 focus:outline-none" required>
<option value="1" selected>Publish</option>
<option value="0">Draft</option>
</select>
</div>
<div class="mb-5">
<label for="content">Content</label>
<textarea
name="content" id="content"
class="
form-control
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none
"
cols="30" rows="10"
required>{{ old('content') }}</textarea>
<!-- error message untuk content -->
@error('content')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="mt-3">
<button type="submit"
class="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded-full shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">
Save
</button>
<a href="{{ route('post.index') }}"
class="inline-block px-6 py-2.5 bg-gray-200 text-gray-700 font-medium text-xs leading-tight uppercase rounded-full shadow-md hover:bg-gray-300 hover:shadow-lg focus:bg-gray-300 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-gray-400 active:shadow-lg transition duration-150 ease-in-out">back</a>
</div>
</form>
</div>
</div>
<script src="https://cdn.tailwindcss.com/?plugins=forms"></script>
<script src="https://cdn.ckeditor.com/4.18.0/standard/ckeditor.js"></script>
<script>
CKEDITOR.replace('content');
</script>
</body>
</html>
Kalau di tutorial sebelumnya (CRUD Laravel 8), kita gunakan summernote untuk menulis konten, di tutorial ini kita coba gunakan CKEditor supaya kita tidak perlu menggunakan Jquery.
Pada baris kode di atas, action pada form mengarah ke route post.store
.
<form action="{{ route('post.store') }}" method="POST">
Route post.store
ini mengarah ke method store()
di dalam PostController
. Sekarang kita buka kembali PostController
, lalu kita tambahkan baris kode pada method store()
untuk menangani proses insert data.
<?php
// ... baris kode sebelumnya
use Illuminate\Support\Str;
class PostController extends Controller
{
// ... baris kode sebelumnya
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|string|max:151',
'content' => 'required',
'status' => 'required|integer'
]);
$post = Post::create([
'title' => $request->get('title'),
'content' => $request->get('content'),
'status' => $request->get('status'),
'slug' => Str::slug($request->get('title'))
]);
return redirect()->route('post.index')
->with('success', 'Post created successfully.');
}
}
Algoritma untuk method store()
ini terbagi menjadi tiga bagian, yaitu validasi, proses insert data dan proses redirect ke halaman daftar post. Pada proses validasi, kita gunakan function validate()
dan kita definisikan aturan validasi untuk field yang akan kita insert ke dalam table posts
, yaitu title
, content
dan status
. Apabila isian form tidak sesuai dengan aturan validasi yang sudah didefinisikan, project akan menampilkan kembali halaman create post dan menampilkan pesan error.
Dan apabila isian form sudah sesuai, proses akan dilanjutkan ke proses insert data. Pada proses insert data, di sini kita gunakan method eloquent create()
. Data yang dapat kita insert ke dalam table sesuai dengan yang sudah kita definisikan di property $fillable
pada model Post
. Untuk slug
, kita gunakan helper dari Laravel 10 untuk generate slug berdasarkan title. Sebelum deklarasi class PostController
, kita import class Illuminate\Support\Str
.
use Illuminate\Support\Str;
Selanjutnya, kita gunakan Str
class untuk generate slug berdasarkan title.
Str::slug($request->get('title'))
Setelah proses insert, web akan ter-redirect route post.index
atau halaman daftar post dan menampilkan flashdata success
.
Tahapan selanjutnya adalah coding fitur untuk memperbaharui data. Pada file index.blade.php
, proses untuk memperbaharui data mengarah ke route post.edit
dan route ini mengarah ke method edit()
pada controller PostController
. Sekarang kita coba tambahkan baris kode pada method edit()
. Buka kembali file controller PostController
, lalu kita tambahkan baris kode pada method edit()
untuk menangani proses menampilkan halaman edit data post.
<?php
// ... baris kode sebelumnya
class PostController extends Controller
{
// ... baris kode sebelumnya
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
}
Bisa kita lihat parameter untuk method edit()
agak berbeda dari biasanya. Kalau di tutorial sebelumnya, kita gunakan $id
, di sini kita coba gunakan model Post
sebagai parameternya atau biasa disebut Route Model Binding
. Dengan menggunakan route model binding, secara otomatis model instance akan diinject langsung ke dalam route sesuai dengan id pada request URI. Selanjutnya model instance ini ditampung di dalam $post
, lalu kemudian dipassing ke view menggunakan compact('post')
. Pada halaman view, isi dari $post
akan ditampilkan pada masing-masing form input.
Selanjutnya kita buat file view sesuai dengan yang sudah kita definisikan pada function view()
yang ada pada method edit()
, yaitu file edit.blade.php
. Kita buat file edit.blade.php
di dalam direktori posts
, lalu kita tambahkan baris kode berikut ini.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Edit Post - Tutorial CRUD Laravel 10 @ qadrlabs.com</title>
</head>
<body>
<div class="container mx-auto mt-10 mb-10 px-10">
<div class="grid grid-cols-8 gap-4 p-5">
<div class="col-span-4 mt-2">
<h1 class="text-3xl font-bold">
EDIT POST
</h1>
</div>
<div class="col-span-4">
</div>
</div>
<div class="bg-white p-5 rounded shadow-sm">
<form action="{{ route('post.update', $post->id) }}" method="POST">
@csrf
@method('PUT')
<div class="mb-5">
<label for="title">Title</label>
<input type="text" class="
form-control
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded-full
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none
" name="title" value="{{ old('title', $post->title) }}" required>
<!-- error message untuk title -->
@error('title')
<div class="bg-red-400 p-2 shadow-sm rounded mt-2">
{{ $message }}
</div>
@enderror
</div>
<div class="mb-5">
<label for="status">Publish Status</label>
<select name="status" class="form-select appearance-none
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding bg-no-repeat
border border-solid border-gray-300
rounded-full
transition
ease-in-out
m-0 focus:text-gray-700 focus:bg-white
focus:border-blue-600 focus:outline-none" required>
<option value="1" {{ old('status', $post->status) == 1 ? 'selected':'' }} >Publish</option>
<option value="0" {{ old('status', $post->status) == 0 ? 'selected':'' }} >Draft</option>
</select>
</div>
<div class="mb-5">
<label for="content">Content</label>
<textarea
name="content" id="content"
class="
form-control
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none
"
cols="30" rows="10"
required>{{ old('content', $post->content) }}</textarea>
<!-- error message untuk content -->
@error('content')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="mt-3">
<button type="submit"
class="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded-full shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">
Update
</button>
<a href="{{ route('post.index') }}"
class="inline-block px-6 py-2.5 bg-gray-200 text-gray-700 font-medium text-xs leading-tight uppercase rounded-full shadow-md hover:bg-gray-300 hover:shadow-lg focus:bg-gray-300 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-gray-400 active:shadow-lg transition duration-150 ease-in-out">back</a>
</div>
</form>
</div>
</div>
<script src="https://cdn.tailwindcss.com/?plugins=forms"></script>
<script src="https://cdn.ckeditor.com/4.18.0/standard/ckeditor.js"></script>
<script>
CKEDITOR.replace('content');
</script>
</body>
</html>
Pada baris kode di atas, $post
kita tampilkan di value pada form input masing-masing. Misalnya untuk title, kita tampilkan pada value form input dengan name.
<input type="text" name="title" value="{{ old('title', $post->title) }}">
Untuk action form, form edit ini mengarah ke route post.update
dengan id sebagai parameternya dan route ini mengarah ke method update()
pada PostController
.
<form action="{{ route('post.update', $post->id) }}" method="POST">
@csrf
@method('PUT')
Selain itu, karena ini proses untuk update data jadi kita tambahkan blade directive @method('PUT')
.
Selanjutnya kita akan menambahkan kode pada method update()
yang akan menangani proses update data. Buka kembali file controller PostController
, lalu kita tambahkan baris kode pada method update()
.
<?php
// ... baris kode sebelumnya
class PostController extends Controller
{
// ... baris kode sebelumnya
public function update(Request $request, Post $post)
{
$this->validate($request, [
'title' => 'required|string|max:151',
'content' => 'required',
'status' => 'required|integer'
]);
$post->update([
'title' => $request->get('title'),
'content' => $request->get('content'),
'status' => $request->get('status'),
'slug' => Str::slug($request->get('title'))
]);
return redirect()->route('post.index')
->with('success', 'Post updated successfully.');
}
}
Sama seperti method edit()
, method update()
juga menggunakan model Post
sebagai parameter. Jadi secara otomatis, $post
ini merupakan instance dari model Post
berdasarkan id pada request URI yang didefinisikan pada action form.
<form action="{{ route('post.update', $post->id) }}" method="POST">
@csrf
@method('PUT')
Algoritma method update()
ini terbagi menjadi tiga bagian, yaitu validasi, proses update data, dan proses redirect ke route post.index
atau halaman daftar post.
Fitur terakhir untuk project kita adalah fitur hapus data post. Buka kembali file controller PostController
, lalu kita tambahkan method destroy()
.
<?php
// ... baris kode sebelumnya
class PostController extends Controller
{
// ... baris kode sebelumnya
public function destroy(Post $post)
{
$post->delete();
return redirect()
->route('post.index')
->with('success', 'Post deleted successfully.');
}
}
Ya, sama seperti method edit()
dan update()
, kita gunakan model Post
sebagai parameter untuk method destroy()
. Method destroy()
ini menangani proses untuk menghapus data berdasarkan id yang terdapat pada request URI yang sebelumnya sudah kita definisikan pada route post.destroy
di form delete pada file index.blade.php
.
Teman-teman bisa buka kembali file index.blade.php
, lalu temukan baris kode berikut ini.
<form onsubmit="return confirm('Apakah Anda Yakin ?');"
action="{{ route('post.destroy', $post->id) }}" method="POST">
@csrf
@method('DELETE')
Pada baris kode di atas, $post->id
pada parameter route akan digunakan sebagai id untuk model instance $post
pada method destroy()
. Selain route post.destroy
yang mengarah ke method destroy()
, kita perlu menambahkan blade directive @method('DELETE')
sebagai tanda action form ini menggunakan HTTP DELETE method.
Kita sudah selesai coding fitur CRUD untuk project kita, dimulai dari fitur menampilkan data, menambahkan data, memperbaharui data dan menghapus data. Sekarang kita bisa coba run project kita. Buka kembali terminal, lalu run command berikut ini.
php artisan serve
Setelah itu buka url http://127.0.0.1:8000/post
di browser. Setelah kita bisa coba tambahkan data, perbaharui data dan hapus data.
Dalam tutorial ini, kita telah mempelajari tentang Laravel 10 dan Tailwindcss untuk membuat aplikasi web dengan fitur CRUD. Setelah mengikuti tutorial ini, kita akan memahami perbedaan antara Laravel 8 dan Laravel 10, khususnya dalam hal fitur dan sintaksis. Kita telah sama-sama belajar cara membuat aplikasi web dari awal hingga akhir, termasuk instalasi, konfigurasi database, dan pembuatan fitur CRUD. Kita juga telah membahas cara menggunakan Tailwindcss untuk merancang tampilan user interface dan meningkatkan kinerja aplikasi web.
Setelah berhasil membuat aplikasi CRUD menggunakan Laravel 10 dan Tailwind CSS, Kita bisa menyimpulkan sejauh ini tidak ada perbedaan untuk codingan di Laravel 10, kecuali beberapa bagian yang menjadi perbedaan laravel 10 dengan laravel sebelumnya seperti.
composer.json
Kedepannya kita bisa lihat penggunaan fitur PHP 8.1 ketika menggunakan laravel 10 ini.artisan
command. Contohnya bisa kita lihat di file controller PostController.php
.Dari hasi belajar kali ini baru dua fitur laravel 10 yang saya temukan, selain percobaan menggunakan tailwind CSS dan penggunaan route model binding.
Kembali ke pertanyaan awal, apakah fokus belajar laravel 8 atau mulai mencoba laravel 10? Menurut saya, terlepas dari versi yang kita gunakan, kita lebih baik fokus ke basic dan memahami konsep dari framework laravel. Sehingga ketika ada rilis versi berapa pun, selama kita paham, kita bisa dengan mudah mempelajarinya.
© 2024 qadrLabs . All rights reserved. 000515268