There is no fixed way but I will try to guide you anyway….
First create database table for Category
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('categoryname');
$table->string('categoryslug')->unique();
$table->timestamps();
});
}
Change your post table like this
basically adding this code :
$table->foreignId(‘category_id’)->constrained(‘categories’)->onDelete(‘cascade’);
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->foreignId('category_id')->constrained('categories')->onDelete('cascade');
$table->timestamps();
});
}
This in category model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $fillable = ['name', 'slug'];
public function posts()
{
return $this->hasMany(Post::class);
}
}
and this in Post Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{ use HasFactory;
protected $fillable = ['title', 'content', 'category_id'];
public function category()
{
return $this->belongsTo(Category::class);
}
}
Now in the create.balde.php file where you create post there
<label for="category">Select Category:</label>
<select name="category_id" id="category" required>
<option value="">-- Choose Category --</option>
@foreach($categories as $category)
<option value="{{ $category['id'] }}">{{ $category['categoryname'] }}</option>
@endforeach
</select>
Now to view this we need to make change at
<div class="container">
@foreach($posts as $post)
<h1>{{$post->title}}</h1>
<h5>{{$post->content}}</h5>
{{ $post->category ? $post->category->categoryname : 'No Category' }}
<hr>
@endforeach
</div>
{{ $post->category ? $post->category->categoryname : ‘No Category’ }}
Now to make dynamic navabr so that we can show the catefory post
Routes
// routes/web.php
use App\Http\Controllers\PostController;
Route::get('/category/{slug}', [PostController::class, 'showByCategory'])->name('category.posts');
Controller method
// app/Http/Controllers/PostController.php
public function showByCategory($slug)
{
// Find category by slug
$category = \App\Models\Category::where('categoryslug', $slug)->firstOrFail();
// Get posts belonging to this category
$posts = $category->posts()->latest()->get();
return view('posts.category', compact('category', 'posts'));
}
navbar methods
<nav>
<ul>
@foreach(\App\Models\Category::all() as $category)
<li>
<a href="{{ route('category.posts', $category->categoryslug) }}">
{{ $category->categoryname }}
</a>
</li>
@endforeach
</ul>
</nav>
Category Page Blade (resources/views/posts/category.blade.php)
<h1>Posts in {{ $category->categoryname }}</h1>
@foreach($posts as $post)
<div>
<h2>{{ $post->title }}</h2>
<p>{{ $post->content }}</p>
<p>Category: {{ $post->category->categoryname }}</p>
</div>
@endforeach
