Laravelのページネーションにクエリ文字列を追加する方法
この記事では、Laravelでページネーションを使用した際に、クエリ文字列をそのページネーションリンクに追加する方法を紹介します。
方法は大きく2つあり、appends()とwithQueryString()というメソッドを使います。
この2つのメソッドの違いについても触れます。
参考にしてみてください。
この記事を読むメリット
- Laravelでページネーションにクエリ文字列を追加できるようになる
- appends()とwithQueryString()の違いが理解できる
ページネーションのページ表示
まずはページネーション表示になっているページの確認をします。
Controller側は以下のように設定しています。
public function paginatedPosts()
{
    $posts = Post::paginate(10);
    return view('paginated-posts')
        ->with('posts', $posts);
}投稿を「paginate()メソッド」で取得します。
このサンプルでは10件ずつ表示できるようpaginate(10)としています。
「with(‘posts’, $posts)」で取得した$postsをblade側に渡しています。
blade側は以下のようにしています。
<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ __('Dashboard') }}
        </h2>
    </x-slot>
    <div id="app">
        <ul class="flex flex-col items-center">
            @foreach ($posts as $post)
              <li class="mb-2 border-b-2">{{ $post->content }}</li>
            @endforeach
        </ul>
        <div class="paginate flex justify-center mt-4">
            {{ $posts->links() }}
        </div>
    </div>
</x-app-layout>
渡ってきた$postsをループで表示させます。
「{{ $posts->links() }}」でページネーションを表示させています。

ページの表示は以下のようになります。
ページ番号をクリックすると、ページ番号のページに遷移して対象の投稿が表示されます。
何も対策をしないとクエリ文字列は消える
先ほどのままだと、クエリ文字を追加した状態で他のページ番号のページに遷移するとクエリ文字は無くなってしまいます。
試しに「query=test」というクエリもURLに追加した状態で、他の番号のページに遷移してみます。

すると、クエリは消えています。

これだとクエリ文字列によってフィルターや検索をかけていた際に、その条件が全て消えた状態になってしまいます。
Laravelのページネーションにクエリ文字列を追加する
これらの対策として2つの方法があります。
クエリ文字列を引き継ぐ方法①withQueryString()
まず1つ目が「withQueryString()」です。
このメソッドを使うと、現在のリクエストのすべてのクエリ文字列値をペジネーションリンクに追加することができます。
「{{ $posts->withQueryString()->links() }}」とlinks()の前にメソッドを追加します。
<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ __('Dashboard') }}
        </h2>
    </x-slot>
    <div id="app">
        <ul class="flex flex-col items-center">
            @foreach ($posts as $post)
            <li class="mb-2 border-b-2">{{ $post->content }}</li>
            @endforeach
        </ul>
        <div class="paginate flex justify-center mt-4">
            {{ $posts->withQueryString()->links() }}
        </div>
    </div>
</x-app-layout>きちんとクエリ文字列が引き継がれました。

クエリ文字列を引き継ぐ方法②appends()
もう1つの方法が「appends()」です。
このメソッドは、引数に渡されたクエリを追加するものです。
以下が例です。
<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ __('Dashboard') }}
        </h2>
    </x-slot>
    <div id="app">
        <ul class="flex flex-col items-center">
            @foreach ($posts as $post)
            <li class="mb-2 border-b-2">{{ $post->content }}</li>
            @endforeach
        </ul>
        <div class="paginate flex justify-center mt-4">
            {{ $posts->appends(request()->query())->links() }}
        </div>
    </div>
</x-app-layout>「appends(request()->query())」でクエリを追加しています。
「request()->query()」で現在保持しているクエリを取得できるので、それを引数に入れています。
Controller側でも設定可能
blade側での設定方法を紹介しましたが、Controller側でも設定が可能です。
public function paginatedPosts(Request $request)
{
    $posts = Post::paginate(10)->withQueryString();
    return view('paginated-posts')
        ->with('posts', $posts);
}「Post::paginate(10)->withQueryString()」とすることで現在のクエリ文字を引き継ぐことができます。
public function paginatedPosts(Request $request)
{
    $posts = Post::paginate(10)->appends($request->query());
    return view('paginated-posts')
        ->with('posts', $posts);
}appends()の場合は、「Post::paginate(10)->appends($request->query())」とすることで実現できます。
さらに、appends()の場合は特定のクエリ文字を指定するときに使えます。
public function paginatedPosts(Request $request)
{
    $posts = Post::paginate(10)->appends([
        'query' => 'test',
        'aaaa' => 'bbbb',
    ]);
    return view('paginated-posts')
        ->with('posts', $posts);
}2つのメソッドの使い分け
これまでappends()とwithQueryString()の使い方を紹介しました。
特徴と使い分けはこんな感じかと思います。
- appends()は特定の指定したいクエリ文字がある際に便利
- withQueryString()はメソッド名から処理内容がわかりやすく記述量も少なくて済む
どちらも同じ結果を得られますが、用途やコードの見やすさを考えて判断するのが良いかと思います。
まとめ
いかがだったでしょうか。
ページネーションはLaravelで簡単に実装できますが、クエリ文字の引き継ぎなどは初めてだったりすると実装忘れもあるかと思います。
この機会に方法をマスターしていただければと思います。
おすすめの記事
同じカテゴリーの新着記事
カテゴリー情報が取得できませんでした。
 
                        

 
                