#14 Laravel基礎

ページネーション

ページネーションとは

ページネーション? データを複数ページに分けて表示する仕組み。100件のデータを1ページ10件ずつ表示するといった用途に使う。 は、大量のデータを複数ページに分けて表示する仕組みです。「1〜10件目」「11〜20件目」のように分割し、ナビゲーションリンクを自動で生成できます。


paginate() の基本

コントローラーで get() の代わりに paginate() を使うだけです。

// 📁 app/Http/Controllers/PostController.php

public function index()
{
    // 1ページあたり15件で分割
    $posts = Post::latest()->paginate(15);
    return view('posts.index', compact('posts'));
}

ビューで $posts を使うとき:

{{-- 📁 resources/views/posts/index.blade.php --}}

@foreach ($posts as $post)
    <div>
        <h2>{{ $post->title }}</h2>
    </div>
@endforeach

{{-- ページネーションリンクを表示 --}}
{{ $posts->links() }}

{{ $posts->links() }} だけでページナビゲーション(前へ・次へ・ページ番号)が表示されます。


URLのクエリパラメーター

paginate() は自動で ?page=2 のようなURLを生成します。

/posts?page=1  → 1〜15件目
/posts?page=2  → 16〜30件目

他の検索条件と組み合わせるときは appends() または withQueryString() を使います。

// 📁 app/Http/Controllers/PostController.php

public function index(Request $request)
{
    $posts = Post::query()
        ->when($request->status, fn($q) => $q->where('status', $request->status))
        ->latest()
        ->paginate(15)
        ->withQueryString(); // ← 現在のクエリパラメーターをリンクに引き継ぐ
        // 例:?status=published&page=2 のように status が維持される

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

simplePaginate

「前のページ・次のページ」のリンクだけで十分な場合(ページ番号不要)は simplePaginate() が効率的です。全件数のカウントSQLが不要になるため、大量データで速くなります。

$posts = Post::latest()->simplePaginate(15);

カスタムページネーションビュー

デフォルトのページネーションデザインはTailwind CSSに対応しています。Bootstrap用もあります。

# ページネーションのビューをカスタマイズするためにファイルを公開
php artisan vendor:publish --tag=laravel-pagination

resources/views/vendor/pagination/ にファイルが展開されます。編集するとデザインを自由に変更できます。

特定のページネーションだけ別のビューを使いたい場合:

{{ $posts->links('vendor.pagination.custom') }}

ページネーション情報の取得

ビューやコントローラーで現在のページ情報を取得できます。

$posts->currentPage();    // 現在のページ番号
$posts->lastPage();       // 最終ページ番号
$posts->total();          // 総件数
$posts->perPage();        // 1ページあたりの件数
$posts->firstItem();      // 現在ページの最初の番号(例:16)
$posts->lastItem();       // 現在ページの最後の番号(例:30)
$posts->hasMorePages();   // 次のページがあるか

使用例:

<p>{{ $posts->total() }}件中 {{ $posts->firstItem() }}{{ $posts->lastItem() }}件を表示</p>

whenで条件付きクエリをスッキリ書く

when() メソッドを使うと、条件付きのクエリを読みやすく書けます。

// 📁 app/Http/Controllers/PostController.php

public function index(Request $request)
{
    $posts = Post::query()
        // $request->status があるときだけ絞り込む
        ->when($request->status, fn ($q, $status) =>
            $q->where('status', $status)
        )
        // $request->keyword があるときだけ検索する
        ->when($request->keyword, fn ($q, $keyword) =>
            $q->where('title', 'like', "%{$keyword}%")
        )
        ->latest()
        ->paginate(15)
        ->withQueryString();

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

まとめ

  • paginate(件数) でページ分割でき、{{ $posts->links() }} でナビゲーションが出る
  • withQueryString() で検索条件をページリンクに引き継げる
  • simplePaginate() はページ番号なしで大量データに向いている
  • when() を使うと検索フォームの条件付きクエリをすっきり書ける

次回はLaravel Breezeを使った認証機能の導入を学びます。