
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、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
文でゴリゴリ書いてました。
・・・ゾッとしますね」