Kita sudah bisa menampilkan post, sekarang saatnya bisa membuatnya lewat form — lengkap dengan validasi supaya data yang masuk selalu valid.
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 menulisifmanualexists:categories,id— validasi bahwacategory_idyang dikirim benar-benar ada di tabelcategoriesstr($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
- Buka
/posts/create - Submit form kosong → harus muncul pesan error "The title field is required."
- 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.