M
Mr Sugiarto
Developer
06 Sep 2026 3 min read

Kita sudah bisa menampilkan post, sekarang saatnya bisa membuatnya lewat form — lengkap dengan validasi supaya data yang masuk selalu valid.

Screenshot: Form create post dengan input judul dan body. Form create post dengan input judul dan body.

Method create()

public function create()
{
    $categories = Category::orderBy('name')->get();

    return view('posts.create', compact('categories'));
}

Kita kirim daftar kategori ke view supaya bisa ditampilkan sebagai dropdown pilihan.

Method store() dengan validasi

public function store(Request $request)
{
    $validated = $request->validate([
        'category_id' => ['nullable', 'exists:categories,id'],
        'title' => ['required', 'string', 'max:255'],
        'body' => ['required', 'string'],
    ]);

    $validated['slug'] = str($validated['title'])->slug();

    $post = Post::create($validated);

    return redirect()->route('posts.show', $post)->with('success', 'Post created successfully.');
}

Beberapa hal penting:

  • $request->validate([...]) — kalau ada aturan yang gagal, Laravel otomatis redirect balik ke form sebelumnya dengan pesan error, tanpa kita perlu menulis if manual
  • exists:categories,id — validasi bahwa category_id yang dikirim benar-benar ada di tabel categories
  • str($validated['title'])->slug() — generate slug otomatis dari judul, misal "Hello World" jadi "hello-world"
  • ->with('success', '...') — flash message yang cuma "hidup" untuk satu request berikutnya (setelah redirect)

Menampilkan error validasi di view

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

<form method="POST" action="{{ route('posts.store') }}">
    @csrf

    <div class="mb-3">
        <label for="title" class="form-label">Title</label>
        <input type="text" name="title" id="title" class="form-control" value="{{ old('title') }}" required>
    </div>
    <!-- ... -->
</form>

Variabel $errors otomatis tersedia di semua view Laravel — tidak perlu di-pass manual dari controller. old('title') mengembalikan input yang tadinya dikirim user (kalau validasi gagal), supaya user tidak perlu ngetik ulang dari nol.

Menampilkan flash message

Kita taruh sekali di layout supaya semua halaman otomatis dapat fitur ini:

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

Testing manual

  1. Buka /posts/create
  2. Submit form kosong → harus muncul pesan error "The title field is required."
  3. Isi title dan body dengan benar → redirect ke halaman detail post dengan alert hijau "Post created successfully."
curl -X POST http://laravel13-blog-dasar.test/posts \
  -d "title=Testing Create Post" -d "body=This is a test body"

(Untuk request sungguhan dari browser, token @csrf otomatis terkirim — request curl manual butuh token CSRF valid dari session yang sama.)

Selanjutnya

Create sudah beres. Episode berikutnya kita lengkapi sisanya: update dan delete post.

M
Mr Sugiarto

Developer

Bagian dari Series: Laravel 13 Dasar — Belajar Fundamental Lewat Blog Sederhana
Lihat Series Lengkap