はじめに
Laravelでバリデーションした結果をVue.jsに引き渡したいのにエラーキャッチできてなくね?って1日ほどハマったので備忘録。
準備(バックエンド)
個人的にControllerクラスでやるよりRequestクラスを作ってバリデーションした方が好きなので。
ちなみに今はこんな感じでディレクトリ切ってます。
directory
App
`--Http
`--Request
+--Hoge
| +--Post.php
| +--Put.php
| `--Delete.php
`--Fuga
+--Post.php
+--Put.php
`--Delete.php
RESTful APIに対応するためにこの構成にしてますが、個人的には割と気に入ってます。
実際はPostとPutくらいしかバリデーションしてないけど…。
Vue.jsのコンポーネントディレクトリはぐちゃぐちゃなので何かいい方法はないだろうかと思案中。
1.バリデーションファイルを作成する
console
php artisan make:request Hoge/Post
# スラッシュ付けるとnamespace自動で補完してくれるのでオススメ
2.バリデーションファイルの中身を編集する
ついでに日本語対応しときます。
翻訳ツール入れてもいいんだけどきめ細やかな対応するならやっぱり自前でメッセージ書かないといけないのかなぁ、と思ってます。
\App\Http\Request\Hoge\Post.php
<?php
namespace App\Http\Requests\Invitation;
use Illuminate\Foundation\Http\FormRequest;
class Post extends FormRequest
{
public function authorize()
{
- return false;
+ return true;
}
public function rules()
{
return [
'hoge' => 'required|min:10|max:20',
];
}
+ public function attributes()
+ {
+ return [
+ 'hoge' => 'ほげ',
+ ];
+ }
+ public function messages()
+ {
+ return [
+ 'hoge.required' => ':attributeは入力必須です。',
+ 'hoge.min' => ':attributeは最低10文字以上で入力してください。',
+ 'hoge.max' => ':attributeは最高20文字までしか入力できません。',
+ ];
+ }
}
3.Controllerクラスからバリデーションするように修正する
\App\Http\Controller\HogeController.php
...
public function store (\App\Http\Request\Hoge\Post $request)
{
// バリデーション通ったあとの処理
}
...
おまけ:ルーティング
routes.api.php
// 特定のメソッドのみ許可
Route::resource('/hoge', 'HogeController', ['only' => ['store', 'update', 'destroy']])
// または特定のメソッドを除外
Route::resource('/hoge', 'HogeController', ['expect' => ['index', 'create', 'show', 'edit']])
/**
* POST : /api/hoge => HogeController@store
* PUT | PATCH : /api/hoge/{id} => HogeController@update
* DELETE : /api/hoge/{id} => HogeController@destroy
*/
実用(フロントエンド)
Hoge.vue
<template>
<div>
<input type="text" v-model="text">
<button @click="hoge">hoge</button>
</div>
</template>
<script>
export default {
data () {
return {
text : null,
}
},
methods : {
hoge () {
let url = '/api/hoge'
let post = { hoge: this.text }
axios.post(url, post)
.then(res => {
console.log('success', res.data)
})
.catch(e => {
console.log(e.response.data.errors)
// あとはエラーメッセージを使ってトーストを出すなり何なりと
})
},
},
}
</script>
まとめ
分かれば簡単なんですけど、 e.response
に気づくまでにかなーり時間がかかってしまいました…。
これで変なことしなくてもバリデーションメッセージをフロントで流用できるやったー!