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();
メルマガ購読の申し込みはこちらから。

