ラボ > Laravel、Lumen:views関連、DB関連

Laravel8 DB::select()にページネーションを使いたい(Facades, Paginator)

Facadesで取得したレコードにページネーションを追加したい

作成日:2022-12-26, 更新日:2023-01-04

基本

▼私の環境
WIN+Docker+Ubuntuでlaravelを使うための作業メモ

通常

▼いろんなサイトを見るとこんな感じ

DB::table('users')->paginate(15);

やりたいこと

「DB::table('users')」とかは複雑なSQLを投げるときが面倒…正確には複雑なSQLを投げる方法を調べるのが面倒
→SQLは分かる。でもクエリビルダやEloquentクエリに変換する方法を都度、調べる時間が腹立たしい

ということで「DB::select($q, $bind)」みたいな感じでレコードを取得し、これにページネーションを追加したい

問題

▼ダメな例

DB::select($q, $bind)->paginate(15)

※「DB::select()」だと配列になるのでエラーになる

対応

データ取得側(コントローラかモデルか…はたまた別の何か)

必要なuse

use Illuminate\Support\Facades\DB; // Facadesのほうを使いたい
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;

select文+ページネーションを追加

$total = ~ 省略 ~; // 総数を取得してくる

$perPage = 10; // 1ページに表示する件数
$page = max(0,Paginator::resolveCurrentPage() - 1); // 現在のページのインデックス番号(「?page=xx」から取得)

$q = 'select * from xxxx where xxxx';

$q .= ' LIMIT :perPage OFFSET :startRecord'; // limit句を追記
$bind = array(
    'perPage' => $perPage,
    'startRecord' => $perPage * $page,
);

$records = DB::select($q, $bind);
if ( !is_array($records) ) {
    $records = array();
}

//ページネータインスタンス生成
$record_many = new LengthAwarePaginator(
    $records,
    $total,
    $perPage,
    null,
    [
        'path' => Paginator::resolveCurrentPath(),
    ]
);

// ==================================
// ▼必要に応じてコメント解除: ペジネーションリンクをゴニョゴニョしたいとき

// $record_many->withPath('/hogehoge'); // リンク先を表示されているURL以外に変更したいとき

// $search_condition_many = array( // getパラメータを追加したいとき
//     'id' => 3,
//     'name' => 'hoge',
// );
// $record_many->appends($search_condition_many);

// $record_many->withQueryString(); // 現在のリクエストのすべてのクエリ文字列値を追加したいとき

// $record_many->fragment('users'); // 「ハッシュフラグメント: #users」を追加したいとき

// ==================================
// ▼ビューに渡す
$viewData = array(
    'record_many' => $record_many,
);
return view('ReserveSimple/Reserved/List', $viewData);

ビュー側

<ul>
    @foreach ($record_many as $record)
        <li>{{ $record->id }}</li>
    @endforeach
</ul>
全 {{ $record_many->total() }} 件
{{ $record_many->links() }}<!-- ページネーションのリンクたち -->

bootstrap.cssのclassに変更したい

「app\Providers\AppServiceProvider.php」に追加

必要なuse: app\Providers\AppServiceProvider.php

use Illuminate\Pagination\Paginator;

boot()の中に追加: app\Providers\AppServiceProvider.php

Paginator::useBootstrap();