How to paginate Models in Laravel Console

Pagination is an essential feature when working with large datasets. There are extensive tutorials on how to implement pagination with Eloquent Models on Websites with Blade etc.

Pagination on Console can be quite as easy using the following Trait. (Be sure to place it in app/Console or updatethe namespace accordingly).

<?php
namespace App\Console;

use function Laravel\Prompts\table;
use function Laravel\Prompts\select;
use function Laravel\Prompts\note;

/**
 * Add Pagination to Eloquent Models in Console
 */
trait PaginateModel {

    /**
     * @param $model - The Eloquent Model to be paginated
     * @param array $columns - Column names selected from the database
     * @param int $perPage - How many items should be listed per page (Optional)
     */
    public function paginateModel($model, array $columns, ?int $perPage = 25): void {

        $page = 1;

        do {
            $users = $model->paginate($perPage, $columns, 'page', $page);

            table(headers: $columns, rows: $users->toArray()['data']);

            note('Current Page: ' . $users->currentPage() . ' / Total Pages: ' . $users->lastPage());

            $choices = [];
            if($users->hasMorePages()) {
                array_push($choices, 'Next');
            }

            if(!$users->onFirstPage()) {
                array_push($choices, 'Previous');
            }

            if(empty($choices)) {
                break;
            }

            $choice = select(label: 'Select next page:', options: $choices);

            if($choice == 'Next' && $users->hasMorePages()) {
                $page++;
            }
            else if($choice == 'Previous' && $page > 1) {
                $page--;
            }
            else {
                break;
            }
        }
        while(true);
    }

}

Usage Example:

<?php

namespace App\Console\Commands\User;

use App\Models\User;
use Illuminate\Console\Command;
use App\Console\PaginateModel;

class ListUsers extends Command {

    use PaginateModel;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'user:list';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'List users.';

    /**
     * Execute the console command.
     */
    public function handle(): void {

        $perPage = 2;
        
        $columns = ['name', 'slug', 'uuid'];

        $users = User::select($columns);

        $this->paginateModel(model: $users, columns: $columns, perPage: $perPage);

    }
}

The Trait uses Laravels Prompts package for handling user input and displaying data. Do not forget to install it before using the trait.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *