Laravel 8系において
JSONd形式のデータをVue.jsのaxiosでPOSTした際、
FormRequestを経由したバリデーションエラーをPOSTされたjsonデータの階層構造と同じ構造で返却したい。
php
1 2<?php 3 4namespace App\Http\Requests\Api; 5 6use Illuminate\Support\Facades\Route; 7use Illuminate\Foundation\Http\FormRequest; 8use Illuminate\Validation\Rule; 9use Illuminate\Http\Exceptions\HttpResponseException; 10use Illuminate\Contracts\Validation\Validator; 11 12class ServiceRequest extends BaseRequest 13{ 14 /** 15 * Determine if the user is authorized to make this request. 16 * 17 * @return bool 18 */ 19 public function authorize() 20 { 21 return true; 22 } 23 24 /** 25 * Get the validation rules that apply to the request. 26 * 27 * @return array 28 */ 29 public function rules() 30 { 31 32 $rules = []; 33 $route_name = Route::currentRouteName(); 34 $method = strtoupper($this->getMethod()); 35 36 if ($method === "POST") { 37 38 // 新規サービス登録 39 if ($route_name === "api.front.service.create") { 40 $rules = [ 41 "owner_id" => [ 42 "required", 43 "integer", 44 Rule::exists("owners", "id"), 45 ], 46 "service_name" => [ 47 "required", 48 "string", 49 "between:1,512" 50 ], 51 "memo" => [ 52 "nullable", 53 "string", 54 "between:0,10240" 55 ], 56 // 当該のサービスが収容できる人数 57 "capacity" => [ 58 "required", 59 "integer", 60 "min:1", 61 ], 62 // 統一価格 63 "price" => [ 64 "required", 65 "integer", 66 ], 67 // 時間単価(時給) 68 "price_per_hour" => [ 69 "required", 70 "integer", 71 ], 72 "service_type" => [ 73 "required", 74 "integer", 75 Rule::in(array_column(Config("const.service_types"), "index")) 76 ], 77 "reservable_times" => [ 78 "required", 79 "array", 80 ], 81 "reservable_times.*" => [ 82 "required", 83 "array", 84 ], 85 "reservable_times.*.reservable_date" => [ 86 "required", 87 "integer", 88 Rule::in(array_column(Config("const.reservable_dates"), "index")), 89 ], 90 "reservable_times.*.reservable_from" => [ 91 // 予約可能開始時間 92 "required", 93 // Rule::in(Config("const.reservable_hours")), 94 ], 95 "reservable_times.*.reservable_to" => [ 96 // 予約可能終了時間 97 "required", 98 // Rule::in(Config("const.reservable_minutes")), 99 ], 100 ]; 101 } 102 } 103 return $rules; 104 } 105} 106
上記のようなFormRequestクラスを作成し、下記のようなJSONデータをaxios経由でPOSTします。
javascript
1// APIサーバとして稼働しているLaravelへ以下をPOST 2{ 3 "service_images": [], 4 "reservable_times": [ 5 { 6 "reservable_date": "", 7 "reservable_from": "", 8 "reservable_to": "", 9 "reservable_from_hour": "", 10 "reservable_from_minute": "", 11 "reservable_to_hour": "", 12 "reservable_to_minute": "" 13 } 14 ], 15 "owner_id": 1 16}
すると、FormRequestクラスを通して
以下のようなバリデーションエラーが取得できました。
javascript
1{ 2 "service_name": [ 3 "The service name field is required." 4 ], 5 "capacity": [ 6 "The capacity field is required." 7 ], 8 "price": [ 9 "The price field is required." 10 ], 11 "price_per_hour": [ 12 "The price per hour field is required." 13 ], 14 "service_type": [ 15 "The service type field is required." 16 ], 17 "reservable_times.0.reservable_date": [ 18 "The reservable_times.0.reservable_date field is required." 19 ], 20 "reservable_times.0.reservable_from": [ 21 "The reservable_times.0.reservable_from field is required." 22 ], 23 "reservable_times.0.reservable_to": [ 24 "The reservable_times.0.reservable_to field is required." 25 ] 26}
そこで、現在困っている点が、postデータであるjsonの中に [reservable_times]というキーにぶら下がる配列の箇所が、
元のJSONの階層を維持せず一次元の配列にフォーマットされてしまっている点です。
これだと、フロント側のVue.jsでエラー表示する際の処理に不都合しか無いので、
上記のレスポンスを
javascript
1{ 2 "service_name": [ 3 "The service name field is required." 4 ], 5 "capacity": [ 6 "The capacity field is required." 7 ], 8 "price": [ 9 "The price field is required." 10 ], 11 "price_per_hour": [ 12 "The price per hour field is required." 13 ], 14 "service_type": [ 15 "The service type field is required." 16 ], 17 "reservable_times": [ 18 { 19 "reservable_date": [ 20 "The reservable_times.0.reservable_date field is required." 21 ], 22 "reservable_from": [ 23 "The reservable_times.0.reservable_from field is required." 24 ], 25 "reservable_to": [ 26 "The reservable_times.0.reservable_to field is required." 27 ] 28 } 29 ] 30}
上記のように、postされたJSONデータと同じ階層でバリデーションエラーを実現したいと考えています。
これを実現するためには、どのような処理をFormRequest側で対処すると実現できるでしょうか?
識者の方よろしくご教授くださいますようお願い致します。
あなたの回答
tips
プレビュー