Laravel

Laravelで一覧ページのページネーションに検索条件をパラメータで渡す方法

Laravelで検索結果一覧ページのページネーション(Painator)リンクに検索条件をパラメータで渡し、検索条件を保持したままページネーションする方法をご紹介します。
(Laravelバージョン6系)

3つのテーブル構造

以下の3つのテーブルを用意しました。listpagesテーブルから商品を登録したユーザーが登録されてるusersテーブル(子)。usersテーブルに登録されてる都道府県id(todofuken_id)と一致するtodofukensテーブル(孫)の都道府県名(prefecture)を表示させます。

listpagesテーブル(親)

名前 説明
id 主キー
product_name 商品名
user_id 商品登録ユーザーID=usersテーブルのid
※usersテーブルのテーブル名から「s」を除いた名前「user」とusersテーブルの主キー「id」にアンダーバー「_」を付けた名前「user_id」にする必要があります。こうすることでusersテーブルからidが一致したデータを取得することができます。

usersテーブル(子)

名前 説明
id 主キー
name ユーザー名
email メールアドレス
todofuken_id 都道府県ID=todofukensテーブルのid
※todofukensテーブルのテーブル名から「s」を除いた名前「todofuken」とtodofukensテーブルの主キー「id」にアンダーバー「_」を付けた名前「todofuken_id」にする必要があります。こうすることでtodofukensテーブルからidが一致したデータを取得することができます。

todofukensテーブル(孫)

名前 説明
id 主キー
prefecture 都道府県名

Laravelで一覧ページのページネーションに検索条件をパラメータで渡すModelの記述

※Listpageモデル、Userモデル、Todofukenモデルのデータを取得する記述をします。

class Listpage extends Model
{
	public function user()
	{
		//Userモデルのデータを取得する
	    return $this->belongsTo('App\User');
	}
	public function todofukens()
	{
		//Todofukenモデルのデータを取得する
	    return $this->belongsTo('App\Todofuken');
	}
}

Laravelで一覧ページのページネーションに検索条件をパラメータで渡すControllerの記述

※listpagesテーブルのuser_idと一致するusersテーブルからidとnameを取得、usersテーブルのtodofuken_idと一致するtodofukensテーブルからidとprefectureを取得します。検索条件としてlistpagesテーブルのproduct_name(商品名)をlike検索します。

namespace App\Http\Controllers;
use Illuminate\Http\Request;

use App\User;   //Userモデルを使用
use App\Todofuken;   //Todofukenモデルを使用
use App\Listpage;   //Listpageモデルを使用


    public function listdata(Request $request)
    {
        $sort = 'listpages.id';
        $order = 'desc';

        $sql = '1=1';

        $product_name = "";
        if(!empty($request->product_name)){
            $product_name = $request->product_name;
            $sql .= " AND listpages.product_name like '%".$request->product_name."%'";
        }

	//listpagesテーブルのuser_idと一致するusersテーブルからidとnameを取得。usersテーブルのtodofuken_idと一致するtodofukensテーブルからidとprefectureを取得。検索条件としてlistpagesテーブルのproduct_name(商品名)をlike検索。
        $listpages = Listpage::with(['user:id,name','user.todofuken:id,prefecture'])
        ->join('users','users.id','=','listpages.user_id')
        ->select('listpages.*','users.id as uid')
        ->whereRaw($sql)
        ->orderBy($sort, $order)->paginate(20);

	//検索条件listpagesテーブルのproduct_name(商品名)とをparamとしてviewに渡す。
        return view('listpages', [
            'listpages' => $listpages,
            'product_name' => $product_name,
            'param' => [
                'product_name' => $product_name,
            ],
        ]);
    }

Laravelで一覧ページのページネーションに検索条件をパラメータで渡すview(一覧ページ)の記述

※ページネーションだけ表示する場合は {{ listpage->links()} }} となりますが、ページネーションに検索条件(商品名:product_name)をパラメータで渡す(保持する)場合は {{ listpage->appends($param)->links()} }}の様にappends()に検索条件をパラメータ($param)として渡せば検索条件を保持しつつページネーションします。

		<form enctype="multipart/form-data" action="{{ url('listpages') }}" method="GET">
	            	@csrf
			<label for="product_name">商品名</label>
			<input type="text" name="product_name" value="{{ old('product_name', $product_name) }}">
			<br>
			<button type="submit">検索</button>
        	</form>

                <div align="center">
                    {{ $listpage->appends($param)->links()}}
                </div>

                <table>
                    <thead>
                        <th>商品名</th>
                        <th>登録ユーザー</th>
                        <th>都道府県</th>
                    </thead>
                    <tbody>
                        @foreach ($listpages as $listpage)
                            <tr>
                                <!-- 商品名 -->
                                <td class="table-text">
                                    <div>{{ $listpage->product_name }}</div>
                                </td>
                                <!-- 登録ユーザー -->
                                <td class="table-text">
                                    <div>{{ $listpage->user->name }}</div>
                                </td>
                                <!-- 都道府県 -->
                                <td class="table-text">
                                    <div>{{ $listpage->user->todofuken->prefecture }}</div>
                                </td>
                            </tr>
                        @endforeach
                    </tbody>
                </table>

Routeの記述

※ページURLは必要に応じて変更して下さい。

Route::get('/listpages', 'ListpagesController@listdata');

 
※流用される場合は自己責任でお願いします。