九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、Laravel
で開発していると、
送信データを加工してバリデーションしたい❗
ってことありませんか?
具体的には、こんな時です。
- フォームで「日付」を入力
- 同じく「時間」も入力
- 「日付 + 時間」が未来の日時ならバリデーション通過
つまり、日付と時間を結合させて入力チェックするってことですね。
そこで!
今回はこの問題を解決するにはどうすればいいかをお届けします。
ひとつずつ見ていきましょう!
「バリデーションがあるとホント楽ですよね😊✨」
開発環境: Laravel 5.6
〜7.x
【追記:2020.3.31】この記事は元々Laravel 5.6
向けの内容に加筆修正したものです。
目次
フォームを作る
まずはテストフォームを作ります。(すでにフォームがある方は次まで読み飛ばしてください)
冒頭の例でフォームを作るとこんな感じです。
ビューはこうなります。
/resources/validation.blade.php
<html> <body> <div> <form method="post" action="/date_time_post"> @csrf <label>日付</label> <br> <input name="date" type="date"> <br> <br> <label>時間</label> <br> <input name="time" type="time"> <br> <br> <button type="submit">送信</button> </form> </div> </body> </html>
※ちなみに、<input type="***">
に「date」とか「time」が使えるようになってきて便利になりましたね❗
フォーム・リクエストを作る
では、バリデーションを作っていきましょう。
以下のコマンドを実行してください。
php artisan make:request DateTimeRequest
これで、「/app/Http/Request/DateTimeRequest.php」が作成されました。
フォーム・リクエストをコントローラーに設置する
実際にバリデーションを作成する前に、このDateTimeRequest
をコントローラーへ設置しておきましょう。
/app/Http/Controllers/HomeController.php
use App\Http\Requests\DateTimeRequest; // 👈 追加 class HomeController extends Controller { public function date_time_post(DateTimeRequest $request) { // 👈 ここ echo 'バリデーションOK!'; } // 省略
※Laravel
ではこのようにするだけでバリデーションが有効になり、もしバリデーションに失敗したら自動でリダイレクトしてくれて、さらにエラーメッセージまで取得することができます。さすがです😉✨
バリデーションを作成する
では、ここから本題です。
バリデーション・ルールを追加していきましょう。
まずは基本の内容から。
- 日付が必須で、正しい日付のみOK
- 時間が必須で、正しい時間のみOK
/app/Http/Requests/DateTimeRequest.php
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class DateTimeRequest extends FormRequest { public function authorize() { return true; // 👈 変更 } public function rules() { // 👇 追加 return [ 'date' => 'required|date', 'time' => 'required|date_format:H:i' ]; } }
※authorize()
は、ログインしているかどうかをチェックするもので、今回は無条件でtrue
を返しています。
バリデーションの前にデータ加工する方法
続いて、「日付 + 時間」でチェックする部分です。
これはLaravel
のバージョンで違ってきます。
Laraveのバージョンが「6.x」以上の場合
Laravel 6.x
からprepareForValidation()
というメソッドが追加され、次のようにして簡単にデータ加工できるようになりました。
/app/Http/Requests/DateTimeRequest.php
// 👇 追加する protected function prepareForValidation() { $date_time = ($this->filled(['date', 'time'])) ? $this->date .' '. $this->time : ''; $this->merge([ 'date_time' => $date_time ]); }
Lravelのバージョンが「6.x」未満の場合
FormRequest
から継承しているall()
メソッドを上書きします。
/app/Http/Requests/DateTimeRequest.php
// 👇 追加する public function all($keys = null) { $results = parent::all($keys); if($this->filled(['date', 'time'])) { $results['date_time'] = $this->input('date') .' '. $this->input('time'); } return $results; }
バリデーションを追加
これで、新しいデータ「date_time」が作成されました。
では、このデータにバリデーションを追加してみましょう。
/app/Http/Requests/DateTimeRequest.php
public function rules() { return [ 'date' => 'required|date', 'time' => 'required|date_format:H:i', 'date_time' => 'after:now' // 👈 ここ ]; }
※after
バリデーションの意味は、「今より未来の日時ならOK!」です。
詳しくは、全53種類!Laravel 5.6のバリデーション実例をご覧ください。
全ソースコード(コピペOK)
ということで、今回開発したフォーム・リクエストが以下になります。
このコードを改造すればより複雑なバリデーションも実現することができるはずですので、ぜひ活用してくださいね。
※太字の部分が、あなたの環境に合わせて変更すべき場所です。
Laravel 6.x以上の場合
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class DateTimeRequest extends FormRequest { public function authorize() { return true; } public function rules() { return [ 'date' => 'required|date', 'time' => 'required|date_format:H:i', 'date_time' => 'after:now' ]; } protected function prepareForValidation() { // 日時をデータに追加 $date_time = ($this->filled(['date', 'time'])) ? $this->date .' '. $this->time : ''; $this->merge([ 'date_time' => $date_time ]); } }
Laravel 6.x未満の場合
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class DateTimeRequest extends FormRequest { public function authorize() { return true; } public function rules() { return [ 'date' => 'required|date', 'time' => 'required|date_format:H:i', 'date_time' => 'after:now' ]; } public function all($keys = null) { // 日時をデータに追加 $results = parent::all($keys); if($this->filled(['date', 'time'])) { $results['date_time'] = $this->input('date') .' '. $this->input('time'); } return $results; } }
おわりに
ということで今回は、送信データを加工してからバリデーションでチェックする方法をお届けしました。
Laravel
って結構こういう「ちょっとレアなケース」にも対応できるように設計されているので、今回のようなパターンだけじゃなく色々と融通が効いて嬉しい限りです。
ぜひみなさんもご活用くださいね。
ではでは〜!
「昔はバリデーションをif
文でゴリゴリ書いてました。
・・・ゾッとしますね😱」