FormValidator::Liteをwrapして使ってみる。
2014年5月15日
そのままでも充分使えそうですが、痒いところに手が届くようにしてみました。
ユーザーのプロフィールを入力するフォームをバリデートする感じで下記を書いてみました。
まずはerror_messageのymlを用意。
サイト内に他のフォームがある場合は、myapp/error_message/*.ymlを用意する感じで。
で、use FormValidator::LiteなMyApp::FormValidatorってのを用意。
package MyApp::FormValidator;
use Object::Simple -base;
hash [qw/form message/];
use FormValidator::Lite;
use Path::Class;
use YAML;
sub new {
my $c = shift;
my $self = $c->SUPER::new(@_);
# ymlを全部読み込み
my $message = {};
my $dir = dir('myapp/error_message');
while ( my $d = $dir->next ) {
my $path = $d;
if ( $d =~ /(\w+?)\.yml$/ ) {
my $yml = YAML::LoadFile( $d );
$message->{ $1 } = $yml;
}
}
$self->message($message);
return $self;
}
sub validator {
my ( $self, $args ) = @_;
my $v = FormValidator::Lite->new( $args->{'req'} );
my $yml = $self->yml->{ $args->{'action'} };
$v->set_message_data( $yml );
my $res = $v->check( @{ $args->{'check'} } );
# この辺はお好みでどうぞ(詳しくは下に)
my $message = {};
if ( $v->has_error ) {
for my $p ( keys %{ $yml->{'param'} } ) {
next unless ( exists $v->get_error_messages_from_param( $p )->[0] );
$message->{ $p } = $v->get_error_messages_from_param( $p )->[0];
}
return {
is_ok => 0,
message => $message,
}
}
return { is_ok => 1 };
}
1;
error_messageをhashに入れなおしてるのは、それぞれのフォームにエラーメッセージ(名前入力フォームには名前のエラーみたいな感じ)を表示する用です。
上とか下にまとめて、ドーンと全部メッセージを出す場合はいらないです。
で、上をuseしてみる。
package MyApp::User;
use CGI;
use MyApp::FormValidator;
my $q = CGI->new();
my $v = MyApp::FormValidator->new();
my $res = $v->validator({
req => $q,
action => 'user', # user.ymlを使う
check => [
name => [qw/NOT_NULL/],
age => [qw/INT/]
]
});
unless ( $res->{'is_ok'} ) {
say $res->{'message'}->{'name'};
say $res->{'message'}->{'age'};
return 1;
}
say 'ok!!';
大体こんな感じで。
これ良く考えたら、Object::Simpleじゃなくて、Class::Accessor::Liteにすれば良かった気がしないでもない。
(FormValidator::Liteの中でClass::Accessor::Lite使ってるので・・・)