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としてアクセスできる。
例などは以下のあたりを参考に