Eu prefiro deixar minhas validacoes juntos com as definicoes dos atributos
dos meus objetos, pois provavelmente eu vou validar um objeto antes de
fazer algo com ele.
Então eu faco o seguinte (o exemplo abaixo é para exemplificar atraves da
analise do mesmo, ele não irá compilar):
Em resumo:
1. defino os campos dentro de um hash, juntos com as validacoes
2. faco um loop para adicionar (com moose) cada campo na classe
3. defino um metodo salvar e esse metodo salvar vai verificar se o atributo
tem alguma validacao que deve ser executada
Entao eu termino com algo assim:
package My::Class;
use Moose;
#meta definicao dos meus atributos.. fica dentro de um hash... os atributos
ainda nao foram declarados
#nelas residem as validacoes, coerce, sql etc tudo que é simples e
relacionado a esse campo
#consigo incluir por exemplo um array com items para eu validar antes de
salvar, etc
#ex
my $attrs = {
'preco' => {
# isa => 'Int', #opcional
req => 1,
validation_regex => '(\d+)', # vou usar isso antes do metodo save
coerce => sub { # Vai executar tambem isso antes do save
my ( $self, $value ) = @_;
$value =~ s|^ +| +\$|g;
$value =~ s|(.+)(,\|\.)00\$|$1|gi;
$value =~ s|\D||gi;
return $value;
},
sql =>
{
"type" => "integer",
"null_value" => 0
},
validacao_extra => [
{
rotulo => 'Verifica se contem numeros na mensagem',
validacao => sub {
my ( $campo ) = @_;
return 1 if "valido" eq "valido";
return 0;
},
msg_erro => "Tem erro nesse campo"
}
,
.... e depois adicionar o "validacao_extra" la ao final no
before_save
... e pronto...
]
},
'url' => {
req => 1,
validation_regex => '^http',
sql => {
type => 'string',
"index" => 'not_analyzed',
}
},
'idade' => {
req => 1,
validation_regex => '(\d+)',
sql => {
"type" => "integer",
"null_value" => 0
},
},
};
# declara cada atributo para esta classe
foreach my $attr ( keys $attrs ) {
#Mete o has dentro do foreach pra declarar cada chave dos meus $attrs
has $attr => (
is => 'rw', #podia vir do meu config la de cima ne...
( exists $attrs->{$attr}->{default} )
? (
default => $attrs->{$attr}->{default}
)
: (),
);
}
#coerce nos valores, é usado antes do metodo save... mas pode muito bem
usar o coerce do moo(u|se)
sub coerce {
my ($self) = @_;
foreach my $attr ( keys %$attrs ) {
if ( exists $attrs->{$attr}->{coerce} && defined $self->$attr ) {
$self->$attr(
$attrs->{$attr}->{coerce}->( $self, $self->$attr ) );
}
}
}
#valida antes de salvar
#pode por exemplo verificar se foi setado e executar o $attrs->{ $attr }->{
validation_regex }, etc
sub validate {
my ($self) = @_;
foreach my $attr ( keys $attrs ) {
return 0
if exists $attrs->{$attr}->{req}
and $attrs->{$attr}->{req} == 1
and !defined $self->$attr;
if ( exists $attrs->{ $attr }->{ validation_regex } ) {
//valida a bagaca
//pode ler de $self, ou receber o valor como parametro da sub
validate, etc
}
}
return 1;
}
#before save...
before 'save' => sub {
my ($self) = @_;
$self->coerce();
};
#save somente se validate
sub save {
my ($self) = @_;
next unless $self->validate();
}
abs,
Hernan
2013/9/3 Blabos de Blebe <[email protected]>
> Na verdade foi até coincidência o Solli tocar no assunto, pq assim como
> mapas, eu ia perguntar isso pra vcs em breve.
>
>
> 2013/9/3 Blabos de Blebe <[email protected]>
>
>> > Blabos, e se você tiver 2 formulários na mesma página, por exemplo, um
>> de login e um de cadastro ? Vai ter que melhorar na gambi né ? heheheheheh
>>
>> Correto.
>>
>> > Se mudar o nome do campo entao… chora hehehe
>>
>> Correto denovo.
>>
>> > Marcar o campo errado em vermelho vai precisar de mais gambi :D
>>
>> Mais ou menos. Eu uso uma alternativa, no exemplo. Mas sim, é melhor
>> marcar o campo com vermelho.
>>
>> > Tem muitas vantagens usar o Data::Manager
>>
>> Correto denovo.
>>
>> O porém é que o meu exemplo é exatamente específico. Um form, quatro
>> campos.
>>
>> Não to dizendo que nao vou usar o Data::Manager, ou alguma solução
>> parecida. Só nao vou usar nessa semana :)
>>
>> As soluções apresentadas são apenas o mais pá-pow que dá pra fazer com
>> *a* hard-restriction desse sprint: tempo; e uma soft-restriction:
>> Data::Manager é novo pra mim.
>>
>> Depois eu refatoro. Tá previsto isso.
>>
>> Tá pronto x Tá bom.
>>
>> No meu caso nesse momento, tá pronto é mandatório. Quem me conhece sabe o
>> quanto eu gosto de gambiarra e o quanto tá custando esse tá pronto.
>>
>> :)
>>
>> []'s
>>
>>
>>
>>
>>
>> 2013/9/3 Lucas Oliveira <[email protected]>
>>
>>>
>>> Blabos, e se você tiver 2 formulários na mesma página, por exemplo, um
>>> de login e um de cadastro ? Vai ter que melhorar na gambi né ? heheheheheh
>>>
>>> Se mudar o nome do campo entao… chora hehehe
>>>
>>> Se precisar fazer um "pirulito" para importar para a base a validação
>>> não é aproveitável… esqueçe
>>>
>>> Marcar o campo errado em vermelho vai precisar de mais gambi :D
>>>
>>> Tem muitas vantagens usar o Data::Manager
>>>
>>>
>>> Em 03/09/2013, às 18:30, Blabos de Blebe <[email protected]> escreveu:
>>>
>>> Opa,
>>>
>>> O meu caso é muito simples (pequeno) e o meu tempo é curto. O que foi
>>> mais rápido pra mim foi essa tosqueria aqui:
>>>
>>> No controller:
>>>
>>> ...
>>> my $errors = [];
>>>
>>> ## not null
>>> foreach my $field ( keys %{$fields} ) {
>>> push @{$errors}, 'empty_' . $field
>>> unless $fields->{$field};
>>> }
>>>
>>> ## unique
>>> foreach my $field (qw{ username email }) {
>>> push @{$errors}, 'already_' . $field
>>> if $rs_user->find( { $field => $fields->{$field} } );
>>> }
>>>
>>> ## invalid email
>>> push @{$errors}, 'invalid_email'
>>> unless Email::Valid->address( $fields->{email} );
>>>
>>> if ( @{$errors} > 0 ) {
>>> $c->stash->{user} = $fields;
>>> $c->stash->{errors} = $errors;
>>> return;
>>> }
>>> ...
>>>
>>> No template:
>>>
>>> [% IF errors.size > 0 %]
>>> <div data-alert class="alert-box alert">
>>> [% FOREACH error IN errors %]
>>> [% msg_block = 'msg_' _ error %]
>>> [% PROCESS $msg_block %]<br>
>>> [% END %]
>>> <a href="#" class="close">×</a>
>>> </div>
>>> [% END %]
>>> ...
>>>
>>> [% BLOCK msg_empty_full_name %]
>>> Você precisa preencher o seu nome completo.
>>> [% END %]
>>>
>>> [% BLOCK msg_empty_username %]
>>> Você precisa preencher o seu username.
>>> [% END %]
>>> ...
>>>
>>>
>>>
>>> Deve ter formas mais inteligentes de fazer isso, mas no momento, a mais
>>> inteligente pra mim, é a que eu consigo fazer mais rápido. Esse é meu
>>> "único" form.
>>>
>>> []'s
>>>
>>>
>>> 2013/9/3 Solli Honorio <[email protected]>
>>>
>>>> Blabos, o que você está imaginando para validar ? Estilo old-school com
>>>> um encadeamento de if ? Dispatch table ? NDA ?
>>>>
>>>> Abraços,
>>>>
>>>> Solli Honorio
>>>>
>>>>
>>>> Em 3 de setembro de 2013 16:35, Blabos de Blebe <[email protected]>escreveu:
>>>>
>>>> Em alguns casos, complexidade é um pouco ponto de vista.
>>>>>
>>>>> Acho que entendi a abordagem do mantovani, mas pro meu caso
>>>>> específico, acho que é também o overhead, já que eu só valido 4 campos em
>>>>> uma situação eventual. Estou cogitando nem usar o Data::Manager.
>>>>>
>>>>> Se fosse um cazilhao de campos sendo validados constantemente, acho
>>>>> que valeira a pena.
>>>>>
>>>>> Mantovani, cuidado pra não ficar aparafusando pregos, certo!?
>>>>>
>>>>> []'s
>>>>>
>>>>>
>>>>> 2013/9/3 Solli Honorio <[email protected]>
>>>>>
>>>>>> Sério mesmo Mantovani que vc acha que um sistema de fila é a solução
>>>>>> para eu validar se todos os campos de um formulário estão dentro do
>>>>>> aguardado para trabalhar no banco de dados ?
>>>>>>
>>>>>> Mantovani, só posso dizer que estou orgulhoso de você... vejo que
>>>>>> você terá um excelente futuro na industria de tecnologia (coisa que eu
>>>>>> não
>>>>>> tive), pois este é bem o comportamento dos vendedores de TI. Você está
>>>>>> agregando complexidade numa lugar que estou tentando agregar simplicidade
>>>>>> :D !!!
>>>>>>
>>>>>> Abraços,
>>>>>>
>>>>>> Solli Honorio
>>>>>>
>>>>>>
>>>>>>
>>>>>> Em 3 de setembro de 2013 14:58, Daniel de Oliveira Mantovani <
>>>>>> [email protected]> escreveu:
>>>>>>
>>>>>> 2013/9/3 Solli Honorio <[email protected]>:
>>>>>>> > Lucas,
>>>>>>> >
>>>>>>> > Obrigado pelo retorno. Ontem a noite estudei o código do
>>>>>>> Data::Manager e ví
>>>>>>> > que realmente não rola fazer o que eu estava querendo fazer
>>>>>>> (passar uma
>>>>>>> > pilha de mensagem e receber de acordo com o contexto) e ai estou
>>>>>>> > encaminhando para a mesma solução que você.
>>>>>>>
>>>>>>> " o que eu estava querendo fazer (passar uma pilha de mensagem e
>>>>>>> receber de acordo com o contexto)"
>>>>>>>
>>>>>>> Shonorio, repetindo o AMQP se encaixa perfeitamente. Eu sugiro que
>>>>>>> você leia o link que eu te enviei. Se um serviço na sua máquina vai
>>>>>>> te
>>>>>>> poupar centenas de linhas de código, talvez nessa situação, nesse
>>>>>>> contexto obscuro no qual não foi definido pelo interlocutor seja uma
>>>>>>> boa.
>>>>>>>
>>>>>>> Se você acha que isso é demais para você, eu sinto muito que alguém
>>>>>>> com pelo menos 15/20 anos de experiência ainda não saiba formular uma
>>>>>>> pergunta. Perguntas genéricas, respostas genéricas. E ainda acho
>>>>>>> extremamente desnecessário o seu ataque gratuito, mas se você ainda
>>>>>>> não percebeu isso afasta as pessoas da lista.
>>>>>>>
>>>>>>> >
>>>>>>> > Como vc faz com o I18N ?
>>>>>>> >
>>>>>>> > O Renato Cron publicou um 'template' (
>>>>>>> https://github.com/AwareTI/MyApp )
>>>>>>> > de como eles estão utilizando o Data::Manager. Estudei o código e
>>>>>>> achei
>>>>>>> > engenhoso, mas ainda quero manter um melhor controle do ResultSet
>>>>>>> porquê
>>>>>>> > quero devolver uma estrutura mais complexa de informação.
>>>>>>> >
>>>>>>> > Abraços,
>>>>>>> >
>>>>>>> > Solli Honorio
>>>>>>> >
>>>>>>> >
>>>>>>> >
>>>>>>> > 2013/9/3 Lucas Oliveira <[email protected]>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> Normalmente eu uso sempre com I18N mas da pra quebrar o galho
>>>>>>> assim
>>>>>>> >>
>>>>>>> >> <code>
>>>>>>> >> #!/usr/bin/env perl
>>>>>>> >>
>>>>>>> >> use common::sense;
>>>>>>> >> use Data::Manager;
>>>>>>> >> use Data::Verifier;
>>>>>>> >>
>>>>>>> >> my %msg_data = (
>>>>>>> >> missing_name_last => 'Nao foi informado o campo name_last, seu
>>>>>>> idiota
>>>>>>> >> !',
>>>>>>> >> );
>>>>>>> >>
>>>>>>> >> sub messages { $msg_data{$_[0]} || $_[0] }
>>>>>>> >>
>>>>>>> >> my $dm = Data::Manager->new;
>>>>>>> >> my $dv = Data::Verifier->new(
>>>>>>> >> filters => [ qw(trim) ],
>>>>>>> >> profile => {
>>>>>>> >> name_first => {
>>>>>>> >> required => 1,
>>>>>>> >> type => 'Str',
>>>>>>> >> filters => [ qw(collapse) ]
>>>>>>> >> },
>>>>>>> >> name_last => {
>>>>>>> >> required => 1,
>>>>>>> >> type => 'Str',
>>>>>>> >> filters => [ qw(collapse) ]
>>>>>>> >> },
>>>>>>> >> age => {
>>>>>>> >> type => 'Int'
>>>>>>> >> },
>>>>>>> >> sign => {
>>>>>>> >> required => 1,
>>>>>>> >> type => 'Str'
>>>>>>> >> }
>>>>>>> >> }
>>>>>>> >> );
>>>>>>> >>
>>>>>>> >> $dm->set_verifier( name => $dv );
>>>>>>> >> $dm->verify( name => { name_first => 'Solli' });
>>>>>>> >>
>>>>>>> >> if (!$dm->success) {
>>>>>>> >> print &messages( $_->msgid ).$/
>>>>>>> >> foreach (@{ $dm->messages->messages });
>>>>>>> >> }
>>>>>>> >> </code>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> Em 02/09/2013, às 11:10, Solli Honorio <[email protected]>
>>>>>>> escreveu:
>>>>>>> >>
>>>>>>> >> Pessoal,
>>>>>>> >>
>>>>>>> >> Estou tentando configurar uma mensagem padronização no
>>>>>>> Data::Manager, mas
>>>>>>> >> não está funcionando. Alguém aqui já utilizou o Data::Manager
>>>>>>> para saber se
>>>>>>> >> é possível fazer isto que eu quero ?
>>>>>>> >>
>>>>>>> >> O código abaixo, estou criando uma mensagem e adicionando no
>>>>>>> Data::Manger,
>>>>>>> >> porquê eu imaginei que quando ocorrer o problema dentro do escopo
>>>>>>> e msgid,
>>>>>>> >> eu teria o texto padronizado, mas o que estou recebendo é mais
>>>>>>> uma pilha de
>>>>>>> >> mensagem, mesmo quando não existe o erro.
>>>>>>> >>
>>>>>>> >> <code>
>>>>>>> >> #!/usr/bin/env perl
>>>>>>> >> use common::sense;
>>>>>>> >> use Data::Manager;
>>>>>>> >> use Data::Verifier;
>>>>>>> >> use Data::Printer;
>>>>>>> >>
>>>>>>> >> my $msg = Message::Stack->new;
>>>>>>> >> $msg->add({
>>>>>>> >> msgid => 'missing_name_last',
>>>>>>> >> level => 'error',
>>>>>>> >> scope => 'name1',
>>>>>>> >> subject => 'name_last',
>>>>>>> >> text => 'Não foi informado o campo name_last, seu idiota
>>>>>>> !'} );
>>>>>>> >>
>>>>>>> >> my $dm = Data::Manager->new( { messages => $msg } );
>>>>>>> >> my $dv = Data::Verifier->new(
>>>>>>> >> filters => [ qw(trim) ],
>>>>>>> >> profile => {
>>>>>>> >> name => {
>>>>>>> >> required => 1,
>>>>>>> >> type => 'Str',
>>>>>>> >> filters => [ qw(collapse) ]
>>>>>>> >> },
>>>>>>> >> age => {
>>>>>>> >> type => 'Int'
>>>>>>> >> },
>>>>>>> >> sign => {
>>>>>>> >> required => 1,
>>>>>>> >> type => 'Str'
>>>>>>> >> }
>>>>>>> >> }
>>>>>>> >> );
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> };
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> $dm->set_verifier('name1', $verifier);
>>>>>>> >> $dm->verify('name1', { name_last => 'Honorio', name_first =>
>>>>>>> 'Solli' });
>>>>>>> >>
>>>>>>> >> my $results = $dm->get_results('name1');
>>>>>>> >> my $stack = $dm->messages_for_scope('name1');
>>>>>>> >>
>>>>>>> >> say $results->success;
>>>>>>> >>
>>>>>>> >> say "Is invalid name_first ", $results->is_invalid('name_first');
>>>>>>> >> say "Is invalid name_last ", $results->is_invalid('name_last');
>>>>>>> # yes
>>>>>>> >>
>>>>>>> >> say "Is missing name_first ", $results->is_missing('name_first');
>>>>>>> # no
>>>>>>> >> say "Is missing is_missing ", $results->is_missing('name_last');
>>>>>>> # yes
>>>>>>> >>
>>>>>>> >> say "Missing count ", $results->missing_count;
>>>>>>> >>
>>>>>>> >> say "Count : ", $stack->count ;
>>>>>>> >> p $stack->get_message( 0 );
>>>>>>> >> p $stack->get_message( 1 );
>>>>>>> >>
>>>>>>> >> </code>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> --
>>>>>>> >> "o animal satisfeito dorme". - Guimarães Rosa
>>>>>>> >> =begin disclaimer
>>>>>>> >> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>> >> SaoPaulo-pm mailing list: [email protected]
>>>>>>> >> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> >> =end disclaimer
>>>>>>> >>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> =begin disclaimer
>>>>>>> >> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>> >> SaoPaulo-pm mailing list: [email protected]
>>>>>>> >> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> >> =end disclaimer
>>>>>>> >>
>>>>>>> >
>>>>>>> >
>>>>>>> >
>>>>>>> > --
>>>>>>> > "o animal satisfeito dorme". - Guimarães Rosa
>>>>>>> >
>>>>>>> > =begin disclaimer
>>>>>>> > Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>> > SaoPaulo-pm mailing list: [email protected]
>>>>>>> > L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> > =end disclaimer
>>>>>>> >
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>>
>>>>>>> -dom
>>>>>>>
>>>>>>> --
>>>>>>>
>>>>>>> Daniel de Oliveira Mantovani
>>>>>>> Business Analytic Specialist
>>>>>>> Perl Evangelist /Astrophysics hobbyist.
>>>>>>> +55 11 9 8538-9897
>>>>>>> XOXO
>>>>>>> =begin disclaimer
>>>>>>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>> SaoPaulo-pm mailing list: [email protected]
>>>>>>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> =end disclaimer
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> "o animal satisfeito dorme". - Guimarães Rosa
>>>>>>
>>>>>> =begin disclaimer
>>>>>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>> SaoPaulo-pm mailing list: [email protected]
>>>>>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>> =end disclaimer
>>>>>>
>>>>>>
>>>>>
>>>>> =begin disclaimer
>>>>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>> SaoPaulo-pm mailing list: [email protected]
>>>>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>> =end disclaimer
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> "o animal satisfeito dorme". - Guimarães Rosa
>>>>
>>>> =begin disclaimer
>>>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>> SaoPaulo-pm mailing list: [email protected]
>>>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>> =end disclaimer
>>>>
>>>>
>>> =begin disclaimer
>>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>> SaoPaulo-pm mailing list: [email protected]
>>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>> =end disclaimer
>>>
>>>
>>>
>>> =begin disclaimer
>>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>> SaoPaulo-pm mailing list: [email protected]
>>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>> =end disclaimer
>>>
>>>
>>
>
> =begin disclaimer
> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
> SaoPaulo-pm mailing list: [email protected]
> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer
>
>
=begin disclaimer
Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
SaoPaulo-pm mailing list: [email protected]
L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
=end disclaimer