【Laravel】Disctinctを使うとEloquentのBuilderでは、Paginatorのtotalが合わない
こんにちは。
ニシザワです。
今回もLaravelの記事です。
タイトル通り、EloquentのBuilderでDistinct()ってやってしまうと、
paginatorのtotalが合わなくなってしまいます。
これは、Laravelのバグです。。。
今まで何回もPRが出てます↓↓
https://github.com/laravel/framework/pulls?q=is%3Apr+columns+getcountforpagination+is%3Aclosed
だが、却下され続けてます。
要するに、後方互換があるので、入れられないのです。
なので、Paginatorクラスから引っ張ってきて独自でPaginationを作ってみました。
下記がコード。
使い方は下記
第三引数にdistinctしたカラムを追加すれば大丈夫です。
ニシザワです。
今回もLaravelの記事です。
タイトル通り、EloquentのBuilderでDistinct()ってやってしまうと、
paginatorのtotalが合わなくなってしまいます。
これは、Laravelのバグです。。。
今まで何回もPRが出てます↓↓
https://github.com/laravel/framework/pulls?q=is%3Apr+columns+getcountforpagination+is%3Aclosed
だが、却下され続けてます。
要するに、後方互換があるので、入れられないのです。
なので、Paginatorクラスから引っ張ってきて独自でPaginationを作ってみました。
下記がコード。
<?php
declare(strict_types=1);
namespace App\Services\Utility\Traits;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
/**
* Trait PaginatorTrait
* @package App\Services\Utility\Traits
*/
trait PaginatorTrait{
/**
* @param Builder $builder
* @param null $perPage
* @param array $columns
* @param string $pageName
* @param null $page
* @return LengthAwarePaginator
*/
private function paginate(Builder $builder, $perPage = null, $columns = ['*'], $pageName = 'page', $page = null) : LengthAwarePaginator
{
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$perPage = $perPage ?: $builder->getModel()->getPerPage();
$results = ($total = $builder->toBase()->getCountForPagination($columns))
? $builder->forPage($page, $perPage)->get($columns)
: $builder->getModel()->newCollection();
return Container::getInstance()->makeWith(LengthAwarePaginator::class, [
'items' => $results,
'total' => $total,
'perPage' => $perPage,
'options' => [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
],
]);
}
}
要するに、Laravelが持っているPaginatorをそのまま持ってきて、必要な箇所を書き換えただけです。使い方は下記
$this->paginate($query,10 ,['tables.id']);
トレイトにしてあるので、そのまま必要なclassに読み込ましてあげれば使えます!!第三引数にdistinctしたカラムを追加すれば大丈夫です。