【Laravel】peginateでLimit句が使えない!ので代替案

Laravelのpaginateメソッドは、元々のクエリで取得した結果に、()の引数で指定した件数で"limit"と"offset"を自動的に設定し処理しています。

(公式のサンプルより)
f:id:daylambsbecomelions:20210829104452p:plain

例えばこの元々のクエリ部分(「DB::table('users')」)で取得する件数を指定したい場合、例えば以下のように記述すれば普通にいけるのかなと思いきや、peginate側で発行されるlimitに上書きされ、自分で書いたlimit句は無視されてしまう。

DB::table('users')->limit(1000)->paginate(15)

では、この元々のクエリにlimitをかけたい場合はどうすればいいのか。検索するとカスタムペジネーションを作るなどの方法が紹介されていたが、大変過ぎるので以下のようなやり方でやってみた。

$subquery = DB::table('users')
                      ->select([
                             row_number() over () as rownum,
                             id,
                             name,
                             email,
                             password,
                      ])
                      ->limit(1000);
$query = DB::table($subquery)->select('*')->where('rownum', '<=', '1000');
$query->paginate(15);

やり方としてはselectに「row_number() over () as rownum(rownum部分は何でもいい)」を追加し、取得した行に連番を振る。その連番を使って行番号を制限したい件数以下に指定して取得し、そのクエリにpeginateをかけるというもの。他にも方法があるかとは思いますが、一応うまくいった実績のある方法として参考に頂ければと思います。