[エラー]Method Illuminate\Support\Collection::paginate does not exist.

##はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回は、Eloquentで取得したテーブルのデータに対してページネーションの設定を試みた際に発生したエラー解決策を共有したいと思います(Qiitaで似たような記事がありそうですが、、、)。

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。

##結論(解決策)
**/Providers/AppServiceProvider.phpでLengthAwarePaginatorのインスタンスを作成する**
下記のように記述すれば、Method Illuminate\Support\Collection::paginate does not exist.を解決できます。

```AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Collection; //追記
use Illuminate\Pagination\LengthAwarePaginator; //追記

class AppServiceProvider extends ServiceProvider
{
    
 //略

    public function boot() //下記内容を追記
    {
        /**
         * Paginate a standard Laravel Collection.
         *
         * @param int $perPage
         * @param int $total
         * @param int $page
         * @param string $pageName
         * @return array
         */
        Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page') {
            $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);

            return new LengthAwarePaginator(
                $this->forPage($page, $perPage)->values(),
                $total ?: $this->count(),
                $perPage,
                $page,
                [
                    'path' => LengthAwarePaginator::resolveCurrentPath(),
                    'pageName' => $pageName,
                ]
            );
        });
    }
}

```

##エラー原因
**``[Error]Method Illuminate\Database\Eloquent\Collection::paginate does not exist.``**
下記のように、Eloquentで取得したUserテーブルのデータに対してページネーションの設定を試みた際にエラーが発生

```php
class UserController extends Controller

{
    public function show(string $name)
    {
        $user = User::where('name', $name)->first()->load(['articles.user', 'articles.likes', 'articles.tags']);

        $articles = $user->articles->sortByDesc('created_at')->paginate(10);

        return view('users.show', compact('user', 'articles'));
    }
```

##調べてみて分かったこと
どうやらLaravelはEloquentコレクションにページネーションを提供していますが、デフォルトでは使用できないらしい。

ちなみに、コレクションには``forPage()メソッド``がありますが、ページネーションリンクは生成されず、私が求めていた機能とは異なるので使用していません。

このような場合、``AppServiceProvider.phpでLengthAwarePaginatorのインスタンスを作成する``必要があることがわかりました。
Eloquentのコレクションと同じ動作をさせたい場合,結論で述べたコードを記述することで可能になるとのこと。

構文と出力がEloquent Collectionのpaginate()メソッドとほぼ同じなので、テストの際に（比較的）簡単にEloquent Collectionと入れ替えることができるそうです。便利そうですね。

##補足1
URLに追加するクエリパラメータを渡す必要がある場合は、下記のようにパラメータの配列を追加することで可能になります。

```php
before
Collection::macro('paginate', function($perPage, $total = null, $page = null, $pageName = 'page') {
//略
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
after
Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page', $queryParams = []//追記) {
//略
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
'query' => $queryParams //追記
]
```

##補足2
今回記述したコードは、基本的に好きな場所に置くことができます。ここでは、AppServiceProvider.phpに入れてエラーを解決していますが、理由としてはほとんどのLaravelアプリケーションがデフォルトでAppServiceProvider.phpが存在しているからです。

##参考文献
https://gist.github.com/simonhamp/549e8821946e2c40a617c85d2cf5af5e

[laravel6.x公式ドキュメント ページネーション ](https://readouble.com/laravel/6.x/ja/pagination.html)