Laravelで複数カラムのvalidation
LaravelのValidationは便利。
http://laravel.com/docs/4.2/validation#basic-usage にある例を引用すると
$validator = Validator::make( array( 'name' => 'Dayle', 'password' => 'lamepassword', 'email' => 'email@example.com' ), array( 'name' => 'required', 'password' => 'required|min:8', 'email' => 'required|email|unique:users' ) );
こんな感じで、第1引数にvalidateしたい配列を、第2引数にvalidationのruleを渡すとvalidationができる。
modelのvalidationをしたい時は、formなりpostのdataなりで受け取ったデータに対してvalidationをかければいいので、例えばこんな感じになる。
$rules = array( 'name' => 'required', 'password' => 'required|min:8', 'email' => 'required|email|unique:users' ); $validator = Validator::make(Input::all(), $rules);
validationは元々色々用意されているけど、これは拡張できる。
http://laravel.com/docs/4.2/validation#custom-validation-rules
アプリケーションによって色々な仕様があるので、独自にvalidationを簡単に拡張できて手軽に使えるのは便利だと思う。
ただ、カラムごとにvalidationする形になっているので、複数のカラムに条件がまたがる場合のvalidationが書けない。(と思っていた)
(そもそも設計が良くないのかもしれないが)こういう場合にcontrollerとかにvalidation的なことを書くと辛くなってくるのでなるべくmodelとかに収めておきたい。
で、書けないと思っていたわけだが、実は書ける。良いやり方かどうかは知らない。
validationの拡張の仕方は2種類ある。
1つはクロージャを使う方法、もう1つはクラスを使う方法。
Validator::extend
を使う点は同じだが、前者は第2引数に直接クロージャで関数を渡す。(例はさっきのページから引用)
Validator::extend('foo', function($attribute, $value, $parameters) { return $value == 'foo'; });
後者は第2引数に呼び出すクラス名を渡す。
Validator::extend('foo', 'FooValidator@validate');
validatorで使うクラスを新たに追加した場合は、それをresolverに登録してあげる必要がある。それが以下のところ。
Validator::resolver(function($translator, $data, $rules, $messages) { return new CustomValidator($translator, $data, $rules, $messages); });
ここで、この$dataには全てのカラムの情報が入っているので、この情報を使うことで、他のカラムの情報も使ってvalidationができる。
これはIlluminate\Validation\Validator
を継承しているクラスでは、$this->data
としてアクセスできる。
例などは以下のあたりを参考に