CRUD adalah singkatan yang berasal dari Create, Read, Update, dan Delete, dimana keempat istilah tersebut merupakan fungsi utama yang nantinya diimplementasikan ke dalam basis data.
Empat poin tersebut mengindikasikan bahwa fungsi utama melekat pada penggunaan database relasional beserta aplikasi yang mengelolanya, seperti Oracle, MySQL, SQL Server, dan lain – lain.
Jika dihubungkan dengan tampilan antarmuka (interface), maka peran CRUD sebagai fasilitator berkaitan dengan tampilan pencarian dan perubahan informasi dalam bentuk formulir, tabel, atau laporan. Nantinya, akan ditampilkan dalam browser atau aplikasi pada perangkat komputer user.
Disini kita akan membuat mengimplementsasi CRUD pada table Category dan Post.
composer create-project Laravel/laravel blog
Nah pada langkah kedua ini kita akan mengupdate database di file .env anda.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password
composer require laravel/breeze --dev
php artisan breeze:install
npm install
npm run dev
php artisan migrate
php artisan make:model Category -m
Akan otomatis terbuat 2 file yaitu :
Sesuaikan kolom pada file database/migrations/*_create_categories_table.php :
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
}
Dari perubahan di atas kita menambahkan 2 field baru dengan type data string.
Jalankan Migrate
php artisan migrate
Supaya field2 dapat ditambahkan atau diubah kita perlu menambahkan properti $fillabel pada file app/Models/Category.php :Supaya field2 dapat ditambahkan atau diubah kita perlu menambahkan properti $fillabel pada file app/Models/Category.php :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $fillable = [
'name',
'slug',
];
}
Membuat dummy jadi sebelum di insert sudah terdapat beberapa data dummy sebelumnya. Buat file database/seeders/CategorySeeder.php :
<?php
namespace Database\Seeders;
use App\Models\Category;
use Illuminate\Database\Seeder;
class CategorySeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$data = [
[
'name' => 'PHP',
'slug' => \Str::slug('PHP'),
'created_at' => now(),
],
[
'name' => 'Python',
'slug' => \Str::slug('Python'),
'created_at' => now(),
],
[
'name' => 'Java',
'slug' => \Str::slug('Java'),
'created_at' => now(),
],
[
'name' => 'C++',
'slug' => \Str::slug('C++'),
'created_at' => now(),
],
[
'name' => 'Ruby',
'slug' => \Str::slug('Ruby'),
'created_at' => now(),
],
];
Category::insert($data);
}
}
php artisan db:seed --class=CategorySeeder
php artisan make:model Post -mcr
Perintah di atas akan membuat 3 file secara bersamaan :
Sesuaikan field pada file database/migrations/*_create_posts_table.php :
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug');
$table->longText('description');
$table->foreignId('category_id')->constrained();
$table->timestamps();
});
}
php artisan migrate
Tambahkan property $fillable untuk fields yang akan diizinkan untuk dimanipulasi.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'slug',
'description',
'category_id',
];
public function category()
{
return $this->belongsTo(Category::class);
}
}
Supaya Controller dapat dibuka kita perlu menambahkan baris route pada file routes/web.php :
Route::resource('posts', PostController::class);
Sebelumnya file Controller sudah otomatis digenerate pada langkah di atas dengan di dalamnya terdapat fungsi bawaan seperti index, create, store, show, edit, update, & destroy.
Sekarang kita akan mengedit file Controller agar benar2 dapat digunakan. Buka file app/Http/Controllers/PostController.php :
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use App\Models\Category;
use Illuminate\Http\Request;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$title= "Post";
$data = Post::with('category')->orderBy('id','desc')->paginate(10);
return view('posts.index',compact('title','data'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$title = 'Post';
$categories = Category::all();
return view('posts.create', compact('title','categories'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'content' => 'required',
'category_id' => 'required|exists:App\Models\Category,id'
]);
Post::create([
'title' => $request->title,
'slug' => \Str::slug($request->title),
'content' => $request->content,
'category_id' => $request->category_id,
]);
return redirect()->route('posts.index')->with('status', 'Post Created Successfully');
}
/**
* Display the specified resource.
*
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function edit(Post $post)
{
$title = 'Post';
$categories = Category::all();
return view('posts.edit', compact('title','categories', 'post'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Post $post)
{
$request->validate([
'title' => 'required|string|max:255',
'content' => 'required',
'category_id' => 'required|exists:App\Models\Category,id',
]);
$post->title = $request->title;
$post->slug = \Str::slug($request->title);
$post->content = $request->content;
$post->category_id = $request->category_id;
$post->save();
return redirect()->route('posts.index')->with('status', 'Post Updated Successfully');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')->with('status', 'Post Delete Successfully');
}
}
Sebelum membuat view kita akan membuat folder baru resources/views/posts .
Buat file baru posts/index.blade.php :
@extends('layouts.app')
@section('content')
@if($message = Session::get('success'))
<div class="alert alert-success">
{{ $message }}
</div>
@endif
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ $title }}</li>
</ol>
</nav>
<div class="card">
<div class="card-header">
<div class="row">
<div class="col col-md-6"><b>{{ $title }}</b></div>
<div class="col col-md-6">
@can('create posts', Post::class)
<a href="{{ route('posts.create') }}" class="btn btn-success btn-sm float-end">Add</a>
@endcan
</div>
</div>
</div>
<div class="card-body">
<table class="table table-bordered">
<tr>
<th>Title</th>
<th>Content</th>
<th>Category</th>
<th>Action</th>
</tr>
@if(count($data) > 0)
@foreach($data as $row)
<tr>
<td>{{ $row->title }}</td>
<td>{{ substr($row->content,1,100) }}</td>
<td>{{ $row->category->name }}</td>
<td>
<form method="post" action="{{ route('posts.destroy', $row->id) }}">
@csrf
@method('DELETE')
<a href="{{ route('posts.show', $row->id) }}" class="btn btn-primary btn-sm">View</a>
<a href="{{ route('posts.edit', $row->id) }}" class="btn btn-warning btn-sm">Edit</a>
<input type="submit" class="btn btn-danger btn-sm" value="Delete" />
</form>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="5" class="text-center">No Data Found</td>
</tr>
@endif
</table>
<div class="py-2">
{!! $data->links() !!}
</div>
</div>
</div>
@endsection('content')
Buat file baru posts/create.blade.php :
@extends('layouts.app')
@section('content')
@if($errors->any())
<div class="alert alert-danger">
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item"><a href="{{route('posts.index')}}">{{ $title }}</a></li>
<li class="breadcrumb-item active" aria-current="page">Edit</li>
</ol>
</nav>
<div class="card">
<div class="card-header">Add {{$title}}</div>
<div class="card-body">
<form method="post" action="{{ route('posts.store') }}">
@csrf
<div class="row mb-3">
<label class="col-sm-2 col-label-form">Title</label>
<div class="col-sm-10">
<input type="text" name="title" class="form-control" />
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-label-form">Category</label>
<div class="col-sm-10">
<select name="category_id" class="form-control">
<option>---</option>
@foreach($categories as $category)
<option value="{{ $category->id }}">{{$category->name}}</option>
@endforeach
</select>
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-label-form">Content</label>
<div class="col-sm-10">
<textarea class="form-control" name="content" rows="3"></textarea>
</div>
</div>
<div class="text-center">
<input type="submit" class="btn btn-primary" value="Add" />
</div>
</form>
</div>
</div>
@endsection('content')
Buat file baru posts/edit.blade.php :
@extends('layouts.app')
@section('content')
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item"><a href="{{route('posts.index')}}">{{ $title }}</a></li>
<li class="breadcrumb-item active" aria-current="page">Edit</li>
</ol>
<div class="card">
<div class="card-header">
<div class="row">
<div class="col col-md-6"><b>{{ $title }}</b></div>
<div class="col col-md-6">
<a href="{{ route('posts.index') }}" class="btn btn-primary btn-sm float-end">View All</a>
</div>
</div>
</div>
<div class="card-body">
<form method="post" action="{{ route('posts.update', $post->id) }}" enctype="multipart/form-data">
@csrf
@method('PUT')
<div class="row mb-3">
<label class="col-sm-2 col-label-form">Title</label>
<div class="col-sm-10">
<input value="{{ $post->title }}" type="text" name="title" class="form-control" />
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-label-form">Category</label>
<div class="col-sm-10">
<select name="category_id" class="form-control">
<option>---</option>
@foreach($categories as $category)
<option value="{{ $category->id }}" {{$category->id==$post->category->id?'selected':''}}>{{$category->name}}</option>
@endforeach
</select>
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-label-form">Content</label>
<div class="col-sm-10">
<textarea class="form-control" name="content" rows="3">{{$post->content }}</textarea>
</div>
</div>
<div class="text-center">
<input type="hidden" name="hidden_id" value="{{ $post->id }}" />
<input type="submit" class="btn btn-primary" value="Update" />
</div>
</div>
</form>
</div>
@endsection('content')
npm run dev
php artisan serve
Untuk fase Produksi jalankan perintah berikut :
npm run build