length: quatro formas para uma opção
Dois cursos anteriores apontaram para cá
Em ActiveRecord: introdução ao model, a aula "Validações: uma regra antes de salvar" apresentou validates como uma regra que o Rails confere antes de salvar um registro. Ela terminava dizendo que as opções, as formas de uma checagem falhar e o jeito de mostrar falhas ao usuário ganhariam um curso próprio. Em ActiveRecord: criando registros, a aula "Quando save retorna false" foi um passo além. Ela mostrou .save devolvendo false quando uma validação falha e article.errors.full_messages explicando o motivo, e apontou para o mesmo curso. Aquele curso também tratou de .save! e .create! levantando ActiveRecord::RecordInvalid, então este não repete o assunto.
Este é esse curso. Ele começa por uma opção que dois models deste projeto já usam: length.
length já tem duas formas neste código
# de Identity::User, o modelo real deste projeto
validates :username, presence: true,
uniqueness: { case_sensitive: false, message: "is not available" },
length: { minimum: 3, maximum: 30 },
format: { with: /\A[a-zA-Z0-9_]+\z/ }
length: { minimum: 3, maximum: 30 } rejeita um username com menos de 3 caracteres ou mais de 30. São dois limites separados no mesmo atributo. Catalog::Course e Catalog::Lesson usam a forma mais simples, com um limite só:
# de Catalog::Course, o modelo real deste projeto
validates :title_en, presence: true, length: { maximum: 255 }
Aqui há limite superior e nenhum inferior. As duas linhas usam a mesma opção length:, com chaves diferentes.
Mais duas formas, testadas numa tabela de rascunho
Nem in: nem is: aparecem neste código hoje. in: recebe um range que define os dois limites de uma vez, e is: exige um comprimento exato. Veja os dois num model descartável, ScratchArticle, criado para esta aula:
class ScratchArticle < ApplicationRecord
validates :title, length: { in: 3..20 }
validates :code, length: { is: 4 }
end
a = ScratchArticle.new(title: "ab")
a.valid?
a.errors[:title]
# => ["is too short (minimum is 3 characters)"]
b = ScratchArticle.new(title: "a" * 25, code: "abc")
b.valid?
b.errors[:title]
# => ["is too long (maximum is 20 characters)"]
b.errors[:code]
# => ["is the wrong length (should be 4 characters)"]
in: 3..20 é minimum: 3, maximum: 20 escrito como um range só, com as mesmas falhas e as mesmas mensagens. is: 4 é mais rígido que os dois. Não é um range: o valor tem um único comprimento permitido.
Quatro chaves, uma opção
minimum, maximum, in e is pertencem todos à mesma opção length:; não são quatro validações diferentes. O model escolhe a forma que combina com a regra: só um limite superior, como o título de Catalog::Course; os dois limites, como o username de Identity::User; um range escrito num valor só; ou um comprimento exato, para algo como um código de tamanho fixo.
O Rails lê as chaves presentes. A mensagem diz qual limite falhou ("too short", "too long", "the wrong length") em vez de um "invalid" genérico.
Pontos-chave
- ActiveRecord: introdução ao model apresentou
validates, e ActiveRecord: criando registros mostrou.savedevolvendofalsecom.errors.full_messagesexplicando o motivo. Este curso continua de onde os dois pararam. length: { minimum:, maximum: }emIdentity::Userelength: { maximum: }emCatalog::Coursesão a mesma opção com chaves diferentes.in:(um range) eis:(um comprimento exato) não aparecem neste código. Numa tabela de rascunho,in: 3..20se comporta comominimum: 3, maximum: 20, eis: 4aceita só aquele comprimento.- Cada forma tem sua mensagem de erro ("too short", "too long", "the wrong length"), que você lê em
.errors[:attribute].
Continue com a aula 2
uniqueness: com escopo, e sem diferenciar maiúsculas de propósito
Unicidade dentro de um grupo com scope:, sem diferenciar maiúsculas com case_sensitive: false, e mensagem própria com message:.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.