Sekarang semua bahan sudah siap — model, relasi, dan data dummy. Saatnya PostController berhenti mengembalikan teks placeholder dan mulai menampilkan data sungguhan.
Halaman daftar post menampilkan data asli dari seeder.
Method index()
public function index()
{
$posts = Post::with('category')->latest()->get();
return view('posts.index', compact('posts'));
}
with('category')— eager load relasi kategori supaya tidak N+1 query di viewlatest()— shortcut untukorderBy('created_at', 'desc')compact('posts')— cara singkat mengirim variabel$postske view dengan nama yang sama
Method show() dengan route model binding
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
Perhatikan: parameternya Post $post, bukan string $id seperti stub bawaan. Ini disebut route model binding — Laravel otomatis mengambil Post berdasarkan ID di URL (/posts/{post}), dan kalau tidak ketemu langsung return 404 otomatis. Kita tidak perlu menulis Post::findOrFail($id) manual.
View index
@forelse ($posts as $post)
<div class="border-bottom py-3 d-flex gap-3">
<div>
<h2 class="h5 mb-1">
<a href="{{ route('posts.show', $post) }}">{{ $post->title }}</a>
</h2>
<p class="text-muted mb-0">
{{ $post->category?->name ?? 'Uncategorized' }}
</p>
</div>
</div>
@empty
<x-alert type="info">No posts yet.</x-alert>
@endforelse
Dua hal menarik di sini:
route('posts.show', $post)— cukup pass object$post, Laravel otomatis ambil ID-nya untuk generate URL yang benar$post->category?->name ?? 'Uncategorized'— operator?->(nullsafe) mencegah error kalau post tidak punya kategori (category_idnull), dikombinasikan??untuk fallback text
@forelse ... @empty ... @endforelse adalah shortcut blade untuk loop yang otomatis menampilkan pesan alternatif kalau collection-nya kosong — menghindari kita menulis @if(count($posts) > 0) manual.
View show
<h1>{{ $post->title }}</h1>
<p class="text-muted">{{ $post->category?->name ?? 'Uncategorized' }}</p>
<div>{{ $post->body }}</div>
Testing
Buka http://laravel13-blog-dasar.test/posts — kamu akan lihat 15 post dari seeder, lengkap dengan nama kategorinya. Klik salah satu judul untuk masuk ke halaman detail.
curl http://laravel13-blog-dasar.test/posts
curl http://laravel13-blog-dasar.test/posts/1
Selanjutnya
Menampilkan data sudah beres. Episode berikutnya kita bikin sisi sebaliknya: form untuk membuat post baru, lengkap dengan validasi input.