【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したカラムを追加すれば大丈夫です。
 
         
         
                 
                 
             
                                             
                                                     
                                                     
                                                     
                                                     
    