LaravelのRoute::resourceで少しはまった話

2018年9月22日

はじめに

Laravelでルーティングを行う際に、

Route::resource

make:controller controllerName --resource

を使用した時に、update処理で少しはまったこと。

環境

Laravel 5.5

updateではまった

まず–resourceを指定してCRUD対応したコントローラを一度に作る。

Route::resource('charas', 'CharasController');
$ php artisan make:controller CharaController --resource

以下の表に対応したコントローラとルーティングが完成。

メソッド URI アクション ルート名
GET /charas index charas.index
GET /charas/create create charas.create
POST /charas store charas.store
GET /charas/{chara} show charas.show
GET /charas/{chara}/edit edit charas.edit
PUT/PATCH /charas/{chara} update charas.update
DELETE /charas/{chara} destroy charas.destroy

createとかは特に問題なく。
っで、アップデートだけはまった。

なぜはまったかというと、formタグのmethodをよくわかっていなかったから。
そもそも、formタグで指定できるmethodはGETとPOSTのみ。
でも、上記表にあるようにアップデートするためにはPUT或いはPATCHのHTTPメソッドを使う必要がある。
うまくいかなかったコードは以下

    @extends('layouts.base')

    @section('content')
        <div class="container">
            <div class="col-sm-offset-2 col-sm-8">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        キャラクターを編集
                    </div>
    
                    <div class="panel-body">
                        <!-- Display Validation Errors -->
                        @include('common.errors')
    
                        <!-- New Characters Form -->
                    <form action="/trncharacters/{{$form->characterid}}" method="PUT" class="form-horizontal">
                            {{ csrf_field() }}
                            <input type="hidden" name="characterid" value="{{$form->characterid}}">
                            <input type="hidden" name="clientid" value="{{$form->clientid}}">
                            <!-- trnCharacter Name -->
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">キャラクタ名</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="name" id="book-name" class="form-control" value="{{ $form->name }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">身長</label>
        
                                    <div class="col-sm-6">
                                        <input type="number" name="height" id="height" class="form-control" value="{{ $form->height }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">体重</label>
        
                                    <div class="col-sm-6">
                                        <input type="number" name="weight" id="weight" class="form-control" value="{{ $form->weight }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">出身地</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="bornIn" id="bornIn" class="form-control" value="{{ $form->bornIn }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">性格</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="personality" id="personality" class="form-control" value="{{ $form->personality }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">経験値取得倍率</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="expRatio" id="expRatio" class="form-control" value="{{ $form->expRatio }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">スキル取得倍率</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="skillRatio" id="skillRatio" class="form-control" value="{{ $form->skillRatio }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">魔法取得倍率</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="magicRatio" id="magicRatio" class="form-control" value="{{ $form->magicRatio }}">
                                    </div>
                            </div>
    
                            <!-- Add Book Button -->
                            <div class="form-group">
                                <div class="col-sm-offset-3 col-sm-6">
                                    <button type="submit" class="btn btn-default">
                                        <i class="fa fa-plus"></i>更新
                                    </button>
                                </div>
                            </div>
                    </form>
                    </div>
                </div>			
            </div>
        </div>
    @endsection

ここでダメだったのは、formタグのメソッドに直接PUTを入れたところ。
じゃあどうやってPUT指定するの?

答えは、
1.formタグにはPOSTを指定
2.

{{ method_field('put') }}

を追加する。

以下がうまくいったコード。

    @extends('layouts.base')

    @section('content')
        <div class="container">
            <div class="col-sm-offset-2 col-sm-8">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        キャラクターを編集
                    </div>
    
                    <div class="panel-body">
                        <!-- Display Validation Errors -->
                        @include('common.errors')
    
                        <!-- New Characters Form -->
                    <form action="/trncharacters/{{$form->characterid}}" method="POST" class="form-horizontal">
                            {{ csrf_field() }}
                            {{ method_field('put') }}
                            <input type="hidden" name="characterid" value="{{$form->characterid}}">
                            <input type="hidden" name="clientid" value="{{$form->clientid}}">
                            <!-- trnCharacter Name -->
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">キャラクタ名</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="name" id="book-name" class="form-control" value="{{ $form->name }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">身長</label>
        
                                    <div class="col-sm-6">
                                        <input type="number" name="height" id="height" class="form-control" value="{{ $form->height }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">体重</label>
        
                                    <div class="col-sm-6">
                                        <input type="number" name="weight" id="weight" class="form-control" value="{{ $form->weight }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">出身地</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="bornIn" id="bornIn" class="form-control" value="{{ $form->bornIn }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">性格</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="personality" id="personality" class="form-control" value="{{ $form->personality }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">経験値取得倍率</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="expRatio" id="expRatio" class="form-control" value="{{ $form->expRatio }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">スキル取得倍率</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="skillRatio" id="skillRatio" class="form-control" value="{{ $form->skillRatio }}">
                                    </div>
                            </div>
                            <div class="form-group">
                                    <label for="task-name" class="col-sm-3 control-label">魔法取得倍率</label>
        
                                    <div class="col-sm-6">
                                        <input type="text" name="magicRatio" id="magicRatio" class="form-control" value="{{ $form->magicRatio }}">
                                    </div>
                            </div>
    
                            <!-- Add Book Button -->
                            <div class="form-group">
                                <div class="col-sm-offset-3 col-sm-6">
                                    <button type="submit" class="btn btn-default">
                                        <i class="fa fa-plus"></i>更新
                                    </button>
                                </div>
                            </div>
                    </form>
                    </div>
                </div>			
            </div>
        </div>
    @endsection

まとめ

・formタグで使えるのはGETとPOSTのみ
・他のHTTPメソッドを使うときは以下を追加する

{{ method_field('対象のメソッド') }}

今回は一度にCRUDを作成する–resourceを使った方法についての話。
仮に違う方法、例えば自分でルーティング設定してメソッド名も自分で使ている場合はわざわざHTTPメソッドを変える必要はない。
あと使わないメソッドとかを消したくなるけど、別途設定したりしないといけなかったりするので注意が必要。
それについては、こちらで解説してあった。
マスターのメンテ画面とかならCRUD全部使いそうなので、要は使いどころって感じだな。

Laravel

Posted by takumioda