PHP
初心者
Laravel

[Laravel 5.6] シンプルなCRUDアプリでレコード更新(生の HTML でフォームを作成するときの注意点)


やりたいこと

Laravel学習帳さんのサイトを参考にLaravelで基本的なCRUDアプリを作成中。

ユーザー情報更新機能を実装するときに少しハマってしまったので、大まかな実装の流れを備忘録としてメモ。

キャプチャ.PNG

↑こんな感じでユーザーの登録や編集、削除ができるアプリです。


環境

CentOS: 7.4

PHP: 7.2

Laravel: 5.6


ルーティングの設定

今回のアプリでは resouce を使ってルーティングを設定しました。


web.php

Route::resource('/user', 'UserController');


この1行で以下のようなルーティングを Laravel 側が勝手に用意してくれます。

ユーザー情報の更新には PUT メソッド使います。

Method
URI
Action
用途

GET
user
index
ユーザーの一覧表示

GET
user/{user}
show
ユーザーの詳細ページ

GET
user/create
create
ユーザー新規登録用のページ

POST
user
store
ユーザーの新規登録

GET
user/{user}/edit
edit
ユーザー情報更新用のページ

PUT/PATCH
user/{user}
update
ユーザー情報の更新

DELETE
user/{user}
destroy
ユーザーの削除


ビューの編集

生の HTML でフォームを作成するとき、以下のように書くとエラーになってしまいます。

<form action="/user/{{$user->id}}" method="PUT">  <!-- PUT の部分に注目 -->

<input type="text" name="name" value="{{ $user->name }}"></input>
<input type="text"name="email" value="{{ $user->email }}"></input>
<input type="text"name="tel" value="{{ $user->tel }}"></input>
<button type="submit">更新</button>
</input>

レコードの更新やから form のメソッドに PUT を指定したろ( ・´ー・`)」

と思っていましたが、HTML のフォームでサポートしているのは GETPOST のみなので、上記のように書いてしまうとエラーになってしまいます。

この場合 type="hidden"input タグを使って、メソッドが PUT であることを明示します。

おまけに Laravel では CSRF 対策がなされていない場合、エラーになってしまいますので、こちらも対策します。

最終的に、下記のようなフォームとなります。

<form action="/user/{{$user->id}}" method="POST">

@csrf <!-- 生のTHMLを書くときは @csrf を忘れずに -->
<input type="hidden" name="_method" value="PUT">

<input type="text" name="name" value="{{ $user->name }}"></input>
<input type="text"name="email" value="{{ $user->email }}"></input>
<input type="text"name="tel" value="{{ $user->tel }}"></input>
<button type="submit">更新</button>
</input>


レコード更新処理でエラーになりやすいポイント



  • form タグで method="PUT" と指定されている

  • CSRF 対策用のトークンが埋め込まれていない

個人的には生の HTML を書くことが多いですが、フォームについては blade テンプレートを使用することもできます。

書き方にバリエーションがありますので興味がある方は調べてみてください。


ちなみに

Laravel 5 では FORM ヘルパーが標準搭載されていません。

私はこちらを参考に導入しましたので参考まで。


コントローラーの処理

最後にビューから送られてきたユーザー情報でデータベースを更新する処理を実装します。

今回はユーザーの名前、メールアドレス、電話番号の3項目を更新します。


UserController.php

public function update(Request $request, $id) {

// 本来はここでバリデーションを実行

// 送られてきた ID でユーザーを特定してインスタンスを生成
$user = User::find($id);

// 送られてきた情報を各プロパティにつっこむ
$user->name = $request->name;
$user->email = $request->email;
$user->tel = $request->tel;

// 保存します。
$user->save();

// ユーザーページへリダイレクト
return redirect("/user/$user->id");
}


以上です。

間違いなどご指摘がありましたコメントをいただければと思います。