「ページネーションのデータを変える」の続きです。検索画面を用意して検索結果をページネーションします。
検索画面のページネーション
まず、こんな検索画面を作りたいです。
検索項目に値を入れると、値により絞り込まれた検索結果が表示されます。ごく普通の検索画面です。画面の右下にはページネーションも表示されます。ここでは1画面に2レコードだけ表示です。
routeの定義は、GETだけで十分です。そう、検索条件はすべてURLに入れます。
...
Route::get('/search', [SearchController::class, 'index'])->name('search');
..
コントローラの作成も簡単です。あまりにも短いのでカットせずにすべて見せてしまいます。
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class SearchController extends Controller
{
public function index(Request $request)
{
$query = User::query();
if ($value = $request->name) {
$query->where('name', 'like', "%{$value}%");
}
if ($value = $request->email) {
$query->where('email', 'like', "%{$value}%");
}
$users = $query->paginate(2);
return view('user.search', compact('users'));
}
}
しかし、このコード大いに問題ありです。先の画面でページネーションの2ページをクリックすると、
検索結果3件だったのに10件になっているし、ページネーションも2ページから5ページに。2ページ目なら表示するのは1件のみでは。
おかしいところだらけです。一番の問題はGETだから、ブラウザのURLには入力した値が追加されるのに、?page=2だけです。
この問題の解決はとても簡単です。
上のコントローラのコードで、withQueryString()を以下のように追加するだけなのです。
...
public function index(Request $request)
{
$query = User::query();
if ($value = $request->name) {
$query->where('name', 'like', "%{$value}%");
}
if ($value = $request->email) {
$query->where('email', 'like', "%{$value}%");
}
$users = $query->paginate(2)->withQueryString(); //ここに追加
return view('user.search', compact('users'));
}
...
修正した2ページ目の画面です。
URLに?email=example.com&page=2とクエリーの文字列が入っていますね。
クエリーをリファクター
上のコントローラのコードでは条件文のifを使い検索のクエリーを作成しています。
それ自体は問題は何もありません。すでに十分わかりやすいです。
しかし、Laravel風にすると以下のようにも書くことができます。
...
class SearchController extends Controller
{
public function index(Request $request)
{
$query = User::query()
->when($request->name, function($query, $value) {
return $query->where('name', 'like', "%{$value}%");
})
->when($request->email, function($query, $value) {
return $query->where('email', 'like', "%{$value}%");
});
$users = $query->paginate(2)->withQueryString();
return view('user.search', compact('users', 'request'));
}
}
...
whereでなくwhenの関数となっているところに注意してください。最初の引数の値が存在するなら次で定義する匿名関数を実行です。
メルマガ購読の申し込みはこちらから。


