Uma das primeira coisas que aprendemos em Rails e que são de grande utilidade são as validações do ActiveRecord. Porém, como as validações são muito fáceis de adicionar e remover, temos que ter certeza que não estamos sobrecarregando nossos usuários com validações.

Por exemplo, supondo que estamos validando o CPF do usuário no cadastro e temos o seguinte código:

1
2
3
4
5
6
7
class User < ActiveRecord::Base
  validates_presence_of :cpf
  validates_length_of :cpf, :is => 11
  validates_numericality_of :cpf
  validates_uniqueness_of :cpf
  validates_as_cpf :cpf # Checa se o cálculo de dígitos é correto
end

Na configuração acima, se o usuário esquece de preencher o campo CPF, deixando-o em branco, nada menos que quatro erros aparecerão para ele:

  • Campo CPF não pode ficar em branco;
  • Campo CPF deve possuir 11 caracteres;
  • Campo CPF deve possuir apenas números;
  • Campo CPF é inválido.

Se o usuário deixou apenas o campo em branco, porque mostrar todos esses erros para ele? Todos os erros mostrados são relevantes?

Ó céus! O que fiz de errado para aparecer tantos erros?

Ó céus! O que fiz de errado para aparecer tantos erros?

Felizmente, a solução é simples, apenas adicione :allow_blank nas validações que elas não serão calculadas caso o campo seja enviado vazio:

1
2
3
4
5
6
7
class User < ActiveRecord::Base
  validates_presence_of :cpf
  validates_length_of :cpf, :is => 11, :allow_blank => true
  validates_numericality_of :cpf, :allow_blank => true
  validates_uniqueness_of :cpf, :allow_blank => true
  validates_as_cpf :cpf, :allow_blank => true
end

Você também pode usar o método Object#with_options adicionado pelo Rails para agrupar as validações:

1
2
3
4
5
6
7
8
9
10
class User < ActiveRecord::Base
  validates_presence_of :cpf
 
  with_options :allow_blank => true do |v|
    v.validates_length_of :cpf, :is => 11
    v.validates_numericality_of :cpf
    v.validates_uniqueness_of :cpf
    v.validates_as_cpf :cpf
  end
end

O campo CPF é apenas um exemplo, mas estamos sobrecarregando os nossos usuários frequentemente nos campos username, e-mail, password e outros.

Não exija a presença de campos confirmação

Um outro tópico que vale a pena ser discutido sobre validações são campos de confirmação. Existe a seguinte nota na documentação do Rails para validates_confirmation_of:

1
2
validates_confirmation_of :password
# Nota: essa validação ocorre apenas se o campo :password_confirmation não for nulo.

E isso é uma feature. Isso significa que nos seus testes ou ao criar um objeto no console, você não precisa passar o campo :password_confirmation:

1
2
3
it "should be valid with valid attributes" do
  User.new(:password => "123456").should be_valid
end

Se por acaso o teste falhar, é porque você adicionou a validação de presença para o campo :password_confirmation, que é desnecessária. Como o campo :password_confirmation estará presente nas views, ele sempre será enviado e portanto sempre será checado, justamente onde é necessário.