TIPS#1 CRUD Laravel 12

Dipublikasikan pada oleh Admin

Website Custom vs Template

Tutorial CRUD Laravel 12: Panduan Lengkap untuk Pemula

CRUD (Create, Read, Update, Delete) adalah fondasi pengelolaan data pada aplikasi web. Artikel ini memandu Anda membangun CRUD sederhana di Laravel 12 dari nol hingga tampil di Blade.

Prasyarat

  • PHP 8.2+, Composer, dan MySQL/MariaDB telah terpasang.
  • Dasar penggunaan terminal/command prompt.

1) Instalasi Laravel

Buat proyek baru:

composer create-project laravel/laravel crud-laravel12
cd crud-laravel12

Atau dengan Laravel installer:

laravel new crud-laravel12

2) Konfigurasi Database

Atur koneksi di .env lalu buat database bernama crud_laravel12 di MySQL.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=crud_laravel12
DB_USERNAME=root
DB_PASSWORD=

3) Generate Model, Migration, Controller

Gunakan artisan untuk membuat paket CRUD bernama Post:

php artisan make:model Post -mcr
  • Model: app/Models/Post.php
  • Migration: database/migrations/<timestamp>_create_posts_table.php
  • Controller: app/Http/Controllers/PostController.php

4) Definisi Skema Tabel (Migration)

Buka file migration create_posts_table.php dan sesuaikan:

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    public function up(): void {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

    public function down(): void {
        Schema::dropIfExists('posts');
    }
};

Jalankan migrasi:

php artisan migrate

5) Model & Mass Assignment

Tambahkan $fillable agar field bisa diisi mass-assignment:

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content'];
}

6) Routing Resource

Daftarkan route resource di routes/web.php:

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::resource('posts', PostController::class);

7) Controller CRUD

Implementasikan method standar di app/Http/Controllers/PostController.php:

<?php
namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::latest()->paginate(5);
        return view('posts.index', compact('posts'));
    }

    public function create()
    {
        return view('posts.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);

        Post::create($validated);

        return redirect()
            ->route('posts.index')
            ->with('success', 'Post berhasil ditambahkan.');
    }

    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    public function edit(Post $post)
    {
        return view('posts.edit', compact('post'));
    }

    public function update(Request $request, Post $post)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);

        $post->update($validated);

        return redirect()
            ->route('posts.index')
            ->with('success', 'Post berhasil diperbarui.');
    }

    public function destroy(Post $post)
    {
        $post->delete();

        return redirect()
            ->route('posts.index')
            ->with('success', 'Post berhasil dihapus.');
    }
}

8) Blade Views (layout, index, form)

8.1 Layout Utama — resources/views/layouts/app.blade.php

<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Laravel 12 CRUD</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <div class="container py-4">
    @yield('content')
  </div>
</body>
</html>

8.2 Index — resources/views/posts/index.blade.php

@extends('layouts.app')

@section('content')
  <div class="d-flex justify-content-between align-items-center mb-3">
    <h2 class="mb-0">Daftar Post</h2>
    <a href="{{ route('posts.create') }}" class="btn btn-primary">Tambah Post</a>
  </div>

  @if (session('success'))
    <div class="alert alert-success">{{ session('success') }}</div>
  @endif

  <table class="table table-bordered align-middle">
    <thead>
      <tr>
        <th style="width:70px">No</th>
        <th>Judul</th>
        <th style="width:220px">Aksi</th>
      </tr>
    </thead>
    <tbody>
      @forelse ($posts as $post)
        <tr>
          <td>{{ $loop->iteration + ($posts->currentPage()-1)*$posts->perPage() }}</td>
          <td>{{ $post->title }}</td>
          <td>
            <a href="{{ route('posts.show', $post) }}" class="btn btn-sm btn-info">Lihat</a>
            <a href="{{ route('posts.edit', $post) }}" class="btn btn-sm btn-warning">Edit</a>
            <form action="{{ route('posts.destroy', $post) }}" method="POST" class="d-inline" onsubmit="return confirm('Yakin hapus?')">
              @csrf
              @method('DELETE')
              <button type="submit" class="btn btn-sm btn-danger">Hapus</button>
            </form>
          </td>
        </tr>
      @empty
        <tr><td colspan="3" class="text-center">Belum ada data.</td></tr>
      @endforelse
    </tbody>
  </table>

  {{ $posts->links() }}
@endsection

8.3 Form Create — resources/views/posts/create.blade.php

@extends('layouts.app')

@section('content')
  <h2 class="mb-3">Tambah Post</h2>

  @if ($errors->any())
    <div class="alert alert-danger">
      <ul class="mb-0">
        @foreach ($errors->all() as $error)
          <li>{{ $error }}</li>
        @endforeach
      </ul>
    </div>
  @endif

  <form action="{{ route('posts.store') }}" method="POST" class="vstack gap-3">
    @csrf
    <div>
      <label class="form-label">Judul</label>
      <input type="text" name="title" class="form-control" value="{{ old('title') }}" required>
    </div>
    <div>
      <label class="form-label">Konten</label>
      <textarea name="content" rows="6" class="form-control" required>{{ old('content') }}</textarea>
    </div>
    <div class="d-flex gap-2">
      <button type="submit" class="btn btn-primary">Simpan</button>
      <a href="{{ route('posts.index') }}" class="btn btn-secondary">Batal</a>
    </div>
  </form>
@endsection

8.4 Form Edit — resources/views/posts/edit.blade.php

@extends('layouts.app')

@section('content')
  <h2 class="mb-3">Edit Post</h2>

  @if ($errors->any())
    <div class="alert alert-danger">
      <ul class="mb-0">
        @foreach ($errors->all() as $error)
          <li>{{ $error }}</li>
        @endforeach
      </ul>
    </div>
  @endif

  <form action="{{ route('posts.update', $post) }}" method="POST" class="vstack gap-3">
    @csrf
    @method('PUT')
    <div>
      <label class="form-label">Judul</label>
      <input type="text" name="title" class="form-control" value="{{ old('title', $post->title) }}" required>
    </div>
    <div>
      <label class="form-label">Konten</label>
      <textarea name="content" rows="6" class="form-control" required>{{ old('content', $post->content) }}</textarea>
    </div>
    <div class="d-flex gap-2">
      <button type="submit" class="btn btn-primary">Perbarui</button>
      <a href="{{ route('posts.index') }}" class="btn btn-secondary">Batal</a>
    </div>
  </form>
@endsection

8.5 Show — resources/views/posts/show.blade.php

@extends('layouts.app')

@section('content')
  <h2 class="mb-3">Detail Post</h2>

  <div class="card">
    <div class="card-body">
      <h4 class="card-title mb-3">{{ $post->title }}</h4>
      <article class="card-text">{{ $post->content }}</article>
    </div>
  </div>

  <div class="mt-3 d-flex gap-2">
    <a href="{{ route('posts.edit', $post) }}" class="btn btn-warning">Edit</a>
    <a href="{{ route('posts.index') }}" class="btn btn-secondary">Kembali</a>
  </div>
@endsection

Opsional: Pagination Bootstrap 5

Aktifkan Bootstrap pagination di App\Providers\AppServiceProvider.php:

use Illuminate\Pagination\Paginator;

public function boot(): void
{
    Paginator::useBootstrapFive();
}

9) Menjalankan Aplikasi

php artisan serve

Buka http://127.0.0.1:8000/posts untuk mencoba CRUD.

Penutup

Anda baru saja membuat CRUD lengkap di Laravel 12: mulai dari migration, model, controller, route resource, hingga tampilan Blade. Selanjutnya Anda bisa menambah fitur seperti pencarian, filter, upload file, atau validasi lanjutan menggunakan Form Request.

← Struktur Website yang Baik untuk SEO TIPS #2 Tutorial CRUD Laravel dan AJAX (2 Part) - Part 1 →

Bangun Bisnis Modern: Website Custom, Kasir Pintar & CRM Cerdas

Pendahuluan Di era persaingan bisnis yang semakin ketat, digitalisasi bukan s...

Baca Selengkapnya →

Apa Itu SEO On-Page? Panduan Lengkap Optimasi Website

Apa Itu SEO On-Page? Panduan Lengkap Optimasi Website SEO On-Page adalah te...

Baca Selengkapnya →

6 Kesalahan SEO Fatal yang Sering Bikin Website Zonks

source image : https://www.freepik.com/free-vector/seo-analysis-isometric-composition-with-web-opt...

Baca Selengkapnya →

9 Alat Content Marketing untuk Memaksimalkan Strategi Konten - Bag 3

7. Trello Konsistensi adalah kunci dalam content marketing. ...

Baca Selengkapnya →

Capek Follow Up Klien Sendiri? Saatnya Punya Sistem yang Kerja Otomatis! | Deby Sejahtera

Kenapa banyak peluang hilang? Respon lambat → calon pelangg...

Baca Selengkapnya →

Ingin Menambah Cabang, Tapi Khawatir Pembukuan? Ini Solusinya untuk UMKM

Ingin Menambah Cabang, Tapi Khawatir Pembukuan? Ini Solusinya untuk UMKM Bagi banyak ...

Baca Selengkapnya →