Route::resource(...)で記述されたrouteに対してRoute model bindingする

# Route model Binding とは
例を上げて説明します。

URIが`/articles/ {id}`のようになってた時
普通ならばcontroller側で`show($id)` のようにして`{id}`の部分を受け取るところを
`/articles/ {article}`　とすることで、controllerに来た時点で
Articleモデルのインスタンスとして受け取ることが出来るという機能です

公式: https://laravel.com/docs/5.6/routing#route-model-binding
参考(日本語): https://laravel10.wordpress.com/2015/03/28/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AElaravel-5-32-route-model-binding/

# resource()に対応する
ルーティングが`get()`や`patch()`で記述されていた場合
Route model Bindingに対応させると下記のようになります

```php
Route::get('articles/{article}', 'ArticleController@show');
Route::patch('articles/{article}', 'ArticleController@update');
```

では、`resource()`をルーティングの定義に使っていた場合
Route model Bindingに対応させようとすると、どうすればいいかを順番に書いていきます

## (1) bindされる部分の名前を把握する
`get()`や`patch()`の場合は、
上記の参考コードに書いたように
bindされる部分の名前は記述しているので明らかですが
`resource()`記述だと何かわかりません。
まずはそこから調べます

アプリケーションdirの配下で`php artisan route:list` を実行してルーティング一覧を出してください
すると、resourceで記述されていた部分も展開され細かいURIが出力されます

```
|        | POST      | articles                                      | articles.store               | App\Http\Controllers\ArticlesController@store                              | web                                    |
|        | GET|HEAD  | articles                                      | articles.index               | App\Http\Controllers\ArticlesController@index                              | web                                    |
|        | GET|HEAD  | articles/create                               | articles.create              | App\Http\Controllers\ArticlesController@create                             | web                                    |
|        | GET|HEAD  | articles/{article}                               | articles.show                | App\Http\Controllers\ArticlesController@show                               | web                                    |
|        | DELETE    | articles/{article}                               | articles.destroy             | App\Http\Controllers\ArticlesController@destroy                            | web                                    |
|        | PUT|PATCH | articles/{article}                               | articles.update              | App\Http\Controllers\ArticlesController@update                             | web                                    |
|        | GET|HEAD  | articles/{article}/edit                          | articles.edit                | App\Http\Controllers\ArticlesController@edit                               | web                                    |
```

すると、bindされる部分の名前が
個々の例において`{article}`であることがわかります

## (2)名前に対してbindするModelを定義する
この定義は、行う必要がある場合とそうでない場合があります

この対応が必要でない場合とは、
bindされる部分(ex: `{article}`) の名前のModelが存在していて、かつ、bindしたいModelの名前と一致している時です。  
ここの例であれば、Articleモデルをbindしたいという要件であれば特にbindの定義は必要ありません

では定義が必要な場合とは
bindされる部分(ex: `{hoge}`) の名前のModelが存在しない、またはbindしたいModelの名前と一致していないときです
こういったことは、URIの構造上起きることはあると思います。

そんなときは、名前に対してbindするModelを定義します

`Providers/RouteServiceProvider.php` に下記のように追記をします

```php:Providers/RouteServiceProvider.php
class RouteServiceProvider extends ServiceProvider
{
    public function boot()
    {
        //

        parent::boot();
        Route::model('hoge', Article::class); // <-追記
    }
}
```
第一引数にbindされる部分(ex: `{hoge}`) の名前
第二引数にbindするModel
を記述してください

## (3)Controller側でモデルのインスタンスを受け取る


```php
class ArticleController extends Controller
{
    public function show(Article $article) // <- 引数にクラスの型宣言をする
    {
        dd($article);
        //
    }
```

これでRoute model bindingは完了です

# bindされる部分の名前を変更したい時どうすればいいか

基本的にbindされる部分の名前は
resouce()の第一引数のnameの部分の単数形が割り当てられます。（不可算名詞ならそのまま)

URIに強いこだわりがなければURIの構造や綺麗さの観点で  
nameの部分を変えるのが良いと私は思います

~~それ以外での方法で。。。となるとresourceの処理を追う限り難しいように見えます~~

~~なので、bindされる部分の名前を変更したい場合は、~~
~~resouce()の第一引数を変更する以外はないかと思われます（知見のある方いたら教えてほしい)~~

コメントいただいた方法でbind名の変更が可能だったので紹介します
[mpyw](https://qiita.com/mpyw)さん、ありがとうございます！！！！

## bind名を上書き変更する

```php:web.php
Route::resource('hoge', 'FugeController')
```
という定義があった時、bindされる部分の名前は`{hoge}`になっています
これを`{hoge}`から`{article}`に変更します

パラメータのマッピングを上書きます

```php:Providers/RouteServiceProvider.php
class RouteServiceProvider extends ServiceProvider
{
    public function boot()
    {
        parent::boot();
        ResourceRegistrar::setParameters(['hoge' => 'article']); // 第一引数に変更対象のbind名、第二引数に変更後のbind名
    }
}
```

そしてrouteの方で
上書きしたマッピングを利用するようにメソッドをアローで追記します

```php:web.php
Route::resource('hoge', 'FugeController')->parameter('hoge', 'article'); // 第一引数に変更対象のbind名、第二引数に変更後のbind名
```

これで `/hoge/{article}`　が実現します
便利。すごい。