laravelproyekblogfullstackMahir4 mnt baca

Proyek Mini: Blog Lengkap

Project capstone: blog dengan auth, kategori, tag, komentar, upload cover, dan policy lengkap.

Arsitektur project

Project penutup ini menggabungkan hampir semua modul: Breeze untuk auth, relasi one-to-many (user-post, post-komentar) dan many-to-many (post-tag), upload cover, policy, pagination, dan seeder. Hasil akhirnya blog multi-user yang layak dipamerkan di portfolio.

Struktur tabel: users, posts (judul, slug, isi, cover, status, user_id, kategori_id), kategoris, komentars (post_id, user_id, isi), dan pivot post_tag.

Langkah 1: model dan relasi

bash
php artisan make:model Post -mfs --policy
php artisan make:model Komentar -m
php artisan make:model Kategori -m
php artisan make:model Tag -m

Flag -mfs membuat migration, factory, seeder sekaligus, dan --policy membuat policy-nya. Definisikan relasi:

php
// app/Models/Post.php
public function user(): BelongsTo { return $this->belongsTo(User::class); }
public function kategori(): BelongsTo { return $this->belongsTo(Kategori::class); }
public function komentars(): HasMany { return $this->komentars()->latest(); }
public function tags(): BelongsToMany { return $this->belongsToMany(Tag::class); }

Langkah 2: controller dengan eager load

php
// app/Http/Controllers/PostController.php
public function index(Request $request)
{
    $posts = Post::with(['user', 'kategori', 'tags'])
        ->withCount('komentars')
        ->where('status', 'published')
        ->when($request->kategori, fn ($q) => $q->whereHas('kategori',
            fn ($q) => $q->where('slug', $request->kategori)))
        ->latest()
        ->paginate(9)
        ->withQueryString();

    return view('posts.index', compact('posts'));
}

public function store(StorePostRequest $request)
{
    $data = $request->validated();
    $data['user_id'] = $request->user()->id;

    if ($request->hasFile('cover')) {
        $data['cover'] = $request->file('cover')->store('covers', 'public');
    }

    $post = Post::create($data);
    $post->tags()->sync($request->input('tags', []));

    return redirect()->route('posts.show', $post);
}

Langkah 3: komentar dan policy

php
// app/Http/Controllers/KomentarController.php
public function store(Request $request, Post $post)
{
    $validated = $request->validate(['isi' => 'required|string|max:1000']);

    $post->komentars()->create([
        'isi' => $validated['isi'],
        'user_id' => $request->user()->id,
    ]);

    return back()->with('sukses', 'Komentar terkirim!');
}

public function destroy(Komentar $komentar)
{
    $this->authorize('delete', $komentar);
    $komentar->delete();
    return back();
}

Policy komentar: pemilik komentar atau pemilik post boleh hapus.

Langkah 4: seed dan verifikasi

bash
php artisan migrate:fresh --seed
php artisan test

Buat seeder yang menghasilkan 5 user, tiap user 8 post dengan 2-4 tag acak dan beberapa komentar. Lalu tulis minimal 3 feature test: tamu tidak bisa posting, pemilik bisa edit postingnya sendiri, user lain tidak bisa edit posting orang.

Catatan teknis: Project ini adalah portfolio piece yang kuat. Sebelum dipamerkan, cek ulang: tidak ada N+1 (pakai Debugbar), semua route tulis terproteksi auth + policy, file upload tervalidasi, dan APP_DEBUG=false kalau di-deploy. Blog sederhana yang aman dan cepat jauh lebih mengesankan daripada fitur banyak tapi bolong.