Practice of Programming

プログラム とか Linuxとかの話題

C::P::FormValidator::Simple::Auto

昨日の続き。DUPLICATIONができない(こちらとかこちら)、ということなので対応してみる。

こんなYAMLで(with: [mail1, mail2] がポイント)

edit_execute:
   mail1:
    - rule: EMAIL
      message: not mail
    - rule: NOT_BLANK
      message: mail1 is required
   mail2:
    - rule: EMAIL
      message: not mail
    - rule: NOT_BLANK
      message: mail2 is required
   mail:
    - rule: DUPLICATION
      with: [mail1, mail2]
      message: mail1 and mail2 must be same.

追記

   mail:
    - rule: DUPLICATION
      with: [mail1, mail2]
      message: mail1 and mail2 must be same.

と書くことで、

 {mail => ['mail1', 'mail2']} => 'DUPLICATION'

というFormValidator::Simpleの書き方に変更します。

こちらで困っているようなケースでも行けるのかもしれないと思いますが、未検証。

{unique => ['id', 'name']} => ['DBIC_UNIQUE', '__c_model(DBIC::Category)__', '!id', 'name']

でしたら、YAMLは以下でいけるかなぁ、と(想像です)。

  unique:
      - rule: [DBIC_UNIQUE, '__c_model(DBIC::Category)__', '!id', 'name']
      - with: ['id', 'name']

追記終わり

patch はこんなん。patchを書き換えて、DEFAULTのバリデーションに追加できるようにして、_USE_DEFAULT_の文字列は、use_default_string と言うconfigの値を見るようにしてみました。

--- /usr/local/share/perl/5.8.4/Catalyst/Plugin/FormValidator/Simple/Auto.pm.back	2007-10-22 10:38:21.000000000 +0900
+++ lib/Catalyst/Plugin/FormValidator/Simple/Auto.pm	2007-10-24 23:36:44.000000000 +0900
@@ -6,6 +6,7 @@
 use Catalyst::Exception;
 use UNIVERSAL::isa;
 use YAML;
+use Clone;
 use FormValidator::Simple;
 
 our $VERSION = '0.15';
@@ -137,13 +138,24 @@
         Catalyst::Exception->throw( message => __PACKAGE__ . qq/: $@/ ) if $@;
 
         $config->{profiles} = $profiles;
+        $config->{profiles_multi} = {};
     }
 
     my $messages;
     my $profiles = $config->{profiles};
+    my $default_validation = Clone::clone $profiles->{DEFAULT};
     for my $action ( keys %{ $profiles || {} } ) {
         my $profile = $profiles->{$action} || {};
 
+        if(my $use_default = delete $profile->{$c->config->{use_default_string} || '_USE_DEFAULT_'}){
+            foreach my $param (@$use_default) {
+                my $rules = $profile->{$param};
+		$profile->{$param} = $default_validation->{$param};
+		if (defined $rules and ref $rules) {
+                    push @{$profile->{$param}}, @$rules;
+                }
+            }
+        }
         for my $param ( keys %$profile ) {
             my $rules = $profile->{$param} || [];
 
@@ -153,7 +165,13 @@
                     my $rule_name = ref $rule->{rule} eq 'ARRAY' ? $rule->{rule}[0] : $rule->{rule};
                     $messages->{$action}{$param} ||= {};
                     $messages->{$action}{$param}{ $rule_name } = $rule->{message} if defined $rule->{message};
-                    $rule = $rule->{rule};
+                    if ( exists $rule->{with} and my @with = @{$rule->{with}} ) {
+                        push @{$config->{profiles_multi}{$action} ||= []}, { $param => \@with } => $rule->{rule};
+                        splice @$rules, $i, 1;
+                        $i--;
+                    } else {
+                        $rule = $rule->{rule};
+                    }
                 }
                 elsif (ref $rule eq 'HASH' and defined $rule->{self_rule} ) {
                     $messages->{$action}{$param} ||= {};
@@ -185,9 +203,11 @@
 sub prepare {
     my $c = shift->NEXT::prepare(@_);
 
-    if ( my $profile = $c->config->{validator}{profiles}{ $c->action->reverse } ) {
-        $c->validator_profile( $c->action->reverse );
-        $c->form(%$profile);
+    my $action = $c->action->reverse;
+    my @profile = (%{$c->config->{validator}{profiles}{ $action } || {} }, @{$c->config->{validator}{profiles_multi}{$action} || []});
+    if ( @profile ) {
+        $c->validator_profile( $action );
+        $c->form(@profile);
     }
 
     $c
@@ -204,12 +224,14 @@
     local $NEXT::NEXT{ $c, 'forward' };
 
     my $res;
-    if ( my $profile = $c->config->{validator}{profiles}{ $action } ) {
+    my @profile = (%{$c->config->{validator}{profiles}{ $action } || {} }, @{$c->config->{validator}{profiles_multi}{$action} || []});
+
+    if ( @profile ) {
         # first time validation
         if (not $c->validator_profile) {
             $c->{validator_profile} = $action;
 
-            $c->form(%$profile);
+            $c->form(@profile);
             $res = $c->NEXT::forward(@_);
         }
         else {
@@ -217,7 +239,7 @@
             local $c->{validator} = FormValidator::Simple->new;
             local $c->{validator_profile} = $action;
 
-            $c->form(%$profile);
+            $c->form(@profile);
             $res = $c->NEXT::forward(@_);
         }
     }

こんな時間なんであんまチェックしてないです...寝よ。


追加したコードに対するテストを書いたら送ろうかなぁ...とか思いますが、self_ruleが何をしているのか追えてない。一応、既存の make test は通るようですが。

# なんか、追記しまくったら、継ぎはぎだらけで気持ち悪いエントリに...。