やりたいこと
Laravel学習帳さんのサイトを参考にLaravelで基本的なCRUDアプリを作成中。
ユーザー情報更新機能を実装するときに少しハマってしまったので、大まかな実装の流れを備忘録としてメモ。
↑こんな感じでユーザーの登録や編集、削除ができるアプリです。
環境
CentOS: 7.4
PHP: 7.2
Laravel: 5.6
ルーティングの設定
今回のアプリでは resouce を使ってルーティングを設定しました。
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 のフォームでサポートしているのは GET
か POST
のみなので、上記のように書いてしまうとエラーになってしまいます。
この場合 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項目を更新します。
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");
}
以上です。
間違いなどご指摘がありましたコメントをいただければと思います。