前回で披露したコントローラー中でのルールの共有のメソッドrules()
では、新規レコード作成と既存レコードの編集における入力項目の違いを、$actionの引数をswitchで分岐して対応しました。今回は、sometimesを使用してそれらの必要性をなくします。
sometimesは、入力項目があるときのみに、それ以降のルールを適応するルールです。tinkerを使ってテストしてみましょう。
通常は、
>>> $input = []; => [] >>> $rules = ['email' => 'required|email']; => [ "email" => "required|email", ] >>> validator($input, $rules)->errors()->all(); => [ "必ず指定してください", ]
とエラーとなるところ、sometimesを使用すると、
>>> $input = []; => [] >>> $rules = ['email' => 'sometimes|required|email']; => [ "email" => "sometimes|required|email", ] >>> validator($input, $rules)->errors()->all(); => [] >>>
とemailの項目が入力にないのにエラーとはなりません。
これを利用して前回のrules()
の定義を書き変えてみます。
namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Validation\Rule; use App\User; class UserController extends Controller { public function rule(User $user = null) { // 共有するルール kana, mailcode, phone_with_dashはカスタムバリデーター $rules = [ 'name' => 'required', 'name_kana' => 'required|kana', 'mailcode' => 'required|mailcode', 'prefecture' => 'required', 'city' => 'required', 'address1' => 'required', 'phone' => 'required|phone_with_dash', 'password' => 'sometimes|required|min:8|max:20|confirmed', 'email' => [ 'required', 'email', Rule::unique('users')->ignore(optional($user)->id), //重複がないかチェック ] ]; return [ // rules $rules, // messages [ 'password.min' => '8から20文字長でお願いします', 'password.max' => '8から20文字長でお願いします' ] // attributes ]; } ... public function store(Request $request) { $request->validate(...$this->rules()); ... } ... public function update(Request $request, User $user) { $request->validate(...$this->rules($user)); ... } ...
前回と変わったのは、関数の引数の$actionとその値によるswitchによる分岐がなくなっています。新規作成時しか必要でない、passwordの項目に、sometimesを使用して、その項目がないときはルールを適用しないようにしています。また、emailの重複のチェックにおいては、以下のようにヘルパーのoptional()
を使用して、新規には存在しない$userの値でundefinedのエラーが出ないようにしています。
Rule::unique('users')->ignore(optional($user)->id)
最後に、sometimes|requiredは以下のようにfilledに置き換えることも可能です。filledに関してはこちらも参考にしてください。
'password' => 'filled|min:8|max:20|confirmed'