M
Mr Sugiarto
Developer
04 Sep 2026 2 min read

Sekarang semua bahan sudah siap — model, relasi, dan data dummy. Saatnya PostController berhenti mengembalikan teks placeholder dan mulai menampilkan data sungguhan.

Screenshot: Halaman daftar post menampilkan data asli dari seeder. 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 view
  • latest() — shortcut untuk orderBy('created_at', 'desc')
  • compact('posts') — cara singkat mengirim variabel $posts ke 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_id null), 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.

M
Mr Sugiarto

Developer

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