Create sudah jalan, sekarang kita lengkapi sisa CRUD: update dan delete. Dua operasi ini secara konsep mirip dengan create, tapi ada satu hal teknis baru yang perlu dipahami: HTML form cuma mendukung method GET dan POST — padahal REST butuh PUT dan DELETE.
Halaman detail post dengan tombol Edit dan Delete.
Method edit() dan update()
public function edit(Post $post)
{
$categories = Category::orderBy('name')->get();
return view('posts.edit', compact('post', 'categories'));
}
public function update(Request $request, Post $post)
{
$validated = $request->validate([
'category_id' => ['nullable', 'exists:categories,id'],
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
]);
$validated['slug'] = str($validated['title'])->slug();
$post->update($validated);
return redirect()->route('posts.show', $post)->with('success', 'Post updated successfully.');
}
Polanya sama persis dengan store(), bedanya cuma $post->update() bukan Post::create() — karena kita mengubah record yang sudah ada, bukan bikin baru. Route model binding lagi-lagi berperan: Post $post otomatis terisi dari {post} di URL.
Method destroy()
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')->with('success', 'Post deleted successfully.');
}
Method spoofing: @method('PUT') dan @method('DELETE')
Karena HTML form asli cuma bisa GET/POST, Laravel memakai trik "method spoofing" — field hidden _method yang memberi tahu Laravel untuk memperlakukan request POST ini seolah PUT atau DELETE.
Form edit:
<form method="POST" action="{{ route('posts.update', $post) }}">
@csrf
@method('PUT')
<!-- input fields -->
<button type="submit">Update Post</button>
</form>
Tombol delete dengan konfirmasi:
<form method="POST" action="{{ route('posts.destroy', $post) }}" onsubmit="return confirm('Delete this post?')">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
onsubmit="return confirm(...)" menampilkan dialog konfirmasi browser sebelum form benar-benar ter-submit — kalau user klik "Cancel", form tidak jadi terkirim.
Kenapa harus form terpisah untuk delete?
Sengaja bukan link <a href="..."> biasa, karena request GET seharusnya tidak mengubah data (prinsip "safe method" di HTTP). Kalau delete dipasang di link <a>, web crawler atau prefetching browser bisa tidak sengaja men-trigger delete. Form dengan method DELETE (via spoofing) jauh lebih aman.
Testing
- Buka salah satu halaman detail post, klik "Edit"
- Ubah title, submit → harus redirect balik ke detail dengan title baru dan flash message hijau
- Klik "Delete" → muncul dialog konfirmasi, setelah confirm post hilang dan redirect ke
/posts
curl -X POST http://laravel13-blog-dasar.test/posts/1 \
-d "_method=DELETE"
Selanjutnya
CRUD teks sudah lengkap. Episode berikutnya kita tambahkan sesuatu yang lebih menarik secara visual: upload gambar thumbnail untuk tiap post.