In Laravel 11, retrieving data from two or more tables has become more straightforward thanks to the Eloquent Relationships and the paginate() method. In this guide, we’ll develop a comprehensive example showing how to implement pagination in Laravel with Relation for these Models in a user-friendly way.
We’ll walk through the entire process, including setting up migrations and models, creating controllers and views, and populating data with Laravel’s artisan commands.
Step 1 – Create Models and Migrations
Begin by generating models and migrations for the tables:
php artisan make:model Category -m
php artisan make:model Post -m
Next, modify the database/migrations/_create_posts_table.php
file to include the following schema:
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug');
$table->text('body');
$table->foreignId('category_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
Similarly, update database/migrations/_create_categories_table.php
with:
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
Execute the migration command:
php artisan migrate
Step 2 – Define Model Relationships
In app/Models/Category.php
, establish the relationship between categories and posts:
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
In app/Models/Post.php
, define the inverse relationship:
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
Step 3 – Seed Dummy Data
Generate a seeder file to populate the tables with sample data:
php artisan make:seeder PostSeeder
Edit database/seeders/PostSeeder.php
to include:
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Post;
use App\Models\Category;
use Illuminate\Support\Str;
class PostSeeder extends Seeder
{
public function run(): void
{
$cat1 = Category::create(['name' => 'Laravel']);
$cat2 = Category::create(['name' => 'Laravel 11']);
$posts = [
[
'title' => 'Laravel Product CRUD Tutorial',
'body' => 'Step by Step Laravel Product CRUD Tutorial',
'category_id' => $cat1->id
],
[
'title' => 'Laravel Image Upload Example',
'body' => 'Step by Step Laravel Image Upload Example',
'category_id' => $cat2->id
],
[
'title' => 'Laravel File Upload Example',
'body' => 'Step by Step Laravel File Upload Example',
'category_id' => $cat2->id
],
[
'title' => 'Laravel Cron Job Example',
'body' => 'Step by Step Laravel Cron Job Example',
'category_id' => $cat1->id
],
[
'title' => 'Laravel Send Email Example',
'body' => 'Step by Step Laravel Send Email Example',
'category_id' => $cat1->id
]
];
foreach ($posts as $post) {
Post::create([
'title' => $post['title'],
'slug' => Str::slug($post['title']),
'body' => $post['body'],
'category_id' => $post['category_id'],
]);
}
}
}
Run the seeder to populate the database:
php artisan db:seed --class=PostSeeder
Step 4 – Add Routes
In routes/web.php
, add a route to handle pagination:
use App\Http\Controllers\PostController;
Route::get('posts', [PostController::class, 'index']);
Step 5 – Create the Controller
Generate a controller to handle business logic:
php artisan make:controller PostController
Edit app/Http/Controllers/PostController.php
to include pagination with related data:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
class PostController extends Controller
{
public function index(Request $request)
{
$posts = Post::with('category')->paginate(4);
return view('posts', compact('posts'));
}
}
Step 6 – Create the Blade View
Create resources/views/posts.blade.php
to display the paginated data:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel 11 Pagination with Relationship Tutorial</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<div class="card mt-5">
<h3 class="card-header p-4">Laravel 11 Pagination with Relationship tutorial</h3>
<div class="card-body mt-4">
<div class="row">
@foreach($posts as $post)
<div class="col-md-3">
<div class="card mt-2" style="width: 18rem;">
<img src="https://picsum.photos/id/0/367/267" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{ $post->title }}</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<button class="btn btn-primary">{{ $post->category->name ?? '' }}</button>
</div>
</div>
</div>
@endforeach
</div>
<div class="mt-3">
{{ $posts->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
</div>
</body>
</html>
Step 7 – Test the Application
Start the Laravel development server:
php artisan serve
Navigate to http://localhost:8000/posts
in your browser to view the paginated posts with their respective categories.