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 →

Fungsi Landing Page dalam Website

Dalam dunia digital marketing, landing page memiliki peran yang sangat penting. Halaman ini bi...

Baca Selengkapnya →

9 Alat Content Marketing untuk Memaksimalkan Strategi Konten - Bag 2

4. Grammarly Grammarly membantu memastikan konten tulisan bebas dar...

Baca Selengkapnya →

Implementasi JWT (JSON Web Token) di Laravel

Implementasi JWT (JSON Web Token) di Laravel untuk Autentikasi Aman JWT atau ...

Baca Selengkapnya →

Black SEO: Pengertian, Teknik, dan Risiko yang Harus Diwaspadai

Black SEO: Pengertian, Teknik, dan Risiko yang Harus Diwaspadai Apa Itu Black SEO? ...

Baca Selengkapnya →

Tren CRM di UMKM: Mengelola Pelanggan Lebih Pintar di Era Digital

Tren CRM di UMKM: Mengelola Pelanggan Lebih Pintar di Era Digital Di tengah persaingan ...

Baca Selengkapnya →

TIPS #3 Tutorial CRUD Laravel dan AJAX (2 Part) - Part 2

Part 2: Implementasi AJAX di Frontend Bagian ini fokus pada interaksi AJA...

Baca Selengkapnya →