FormRequestのバリデーションを問題なくパスしたら、コントローラで$request->validated
で配列としてフォームの入力値を取得できます。取得後の値は安全なのでそのままDBに保存することも可能です。しかし、その配列から必要のない値を抜いたり、足りない値を追加したりとかの処理はどうするかという説明です。
会員登録のFormRequest
例として会員登録の画面を使います。画面はこんな感じです。
その画面の入力をチェックするFormRequestは以下と定義します。
namespace App\Http\Requests; use App\Rules\CaptchaRule; use App\Rules\CustomerPasswordRule; use Illuminate\Foundation\Http\FormRequest; class CustomerRequest extends FormRequest { public function rules() { $rules = [ 'email' => ['required', 'email', 'unique:customer,email'], 'password' => ['required', new CustomerPasswordRule, 'confirmed'], 'name' => ['required'], 'g-recaptcha-response' => ['required', new CaptchaRule], ]; return $rules; } }
CustomerPasswordRuleやCaptchaRuleは事前に用意したカスタムのバリデーションのクラスです。
CustomerRequestのバリデーションを問題なく通過したら、以下のようにコントローラでDBに保存します。
namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use App\Http\Requests\CustomerRequest; use App\Models\Customer; use Illuminate\Foundation\Auth\RegistersUsers; class RegisterController extends Controller { use RegistersUsers; ... /** * 会員の登録 * * @param \App\Http\Requests\CustomerRequest $request * @return \Illuminate\Http\RedirectResponse */ public function register(CustomerRequest $request) { $validated = $request->validated(); Customer::create($validated); ... } }
ここでのregister()
メソッドの$validated
の値の中身を見てみましょう。
$validated = [ "email" => "test@example.com", "password" => "Test1234567890!", "name" => "テスト太郎", "g-recaptcha-response" => "03AGdBq26f1ycQWiqz2OeBFz....", ]
DBに保存するのに必要なのは、email, password(暗号化する)、nameの3つだけで、キャプチャのg-recaptach-responseは必要でありませんので、先の配列値から抜く必要あります。また、会員が有効かどうかを指定するactive_flagが必要なので、その値を配列に加える必要あります。
このような処理を行うには、Laravelのバージョン8.x以降では、以下のようにvalidated()
を使わずに、safe()
, merge()
, except()
を使って可能です。
... $input = $request->safe() ->merge(['active_flag' => 'Y']) ->except(['g-recaptcha-response']); Customer::create($input); ...
safeは、バリデーションをパスした値を抽出し、mergeは値を追加、exceptは値を削除です。しかし、mergeとexceptの使用の順番には注意してください。これらを逆にするとエラーとなってしまいます。なぜなら、exceptは配列を返すのでその後にメソッドの連結ができません。
処理の結果の配列は、以下のようになります。
$input = [ "email" => "test@example.com", "password" => "Test1234567890!", "name" => "テスト太郎", "active_flag" => "Y", ]
よりフレキシブルな処理を望むなら、以下のようにcollect()
を通してCollectionのオブジェクトにすることです。
... $input = $request->safe() ->collect() ->except(['g-recaptcha-response']) ->merge(['active_flag' => 'Y']) ->all(); Customer::create($input); ...
さて、safe()
の対応がないLaravel 7.xではどう対応しましょう。
こちらも、配列をCollectionにしてしまえば、問題ありません。
... $input = collect($request->validated()) ->except(['g-recaptcha-response']) ->merge(['active_flag' => 'Y'] ->all(); Customer::create($input); ...
私としては、Collectionを使用した方が好きです。
以下のように、ケースにより配列の中身を変えることも簡単です。
$input = collect($request->validated()) ->when(! $request->active_flag, function ($collection) { return $collection->put('active_flag', 'N'); // 値がないときはNとする }) ->when(! $request->paymethod_id, function ($collection) { $collection->forget([ // 値がないときは、以下の設定は必要ではない 'paymethod_id', 'card_number', 'card_exp', 'card_holder', ]); return $collection; }) ->all();メルマガ購読の申し込みはこちらから。