Mensagens personalizadas com validates

17 de abril de 2007  |  Ruby on Rails  | 

Um problema que temos com os validates é que ele insiste em colocar o nome do campo na frente da mensagem, mesmo quando personalizamos ela usando o :message.
[source:ruby]validates_presence_of :title,
:message => “O campo ‘Título’ deve ser preenchido”[/source]
Na nossa view ficaria assim:

  • Title O campo ‘Título’ deve ser preenchido

Como resolver isto?

Crie um arquivo .rb qualquer dentro da pasta lib com o seguinte conteúdo:
[source:ruby]module ActiveRecord
class Errors
def add(attribute, msg = @@default_error_messages[:invalid])
if replace_message?(msg)
msg = replace_message(attribute, msg)
attribute = :base
end

@errors[attribute.to_s] = [] if @errors[attribute.to_s].nil?
@errors[attribute.to_s] << msg
end

# true se a mensagem for alterável

def replace_message?(msg)
(msg =~ /{?}/) || (msg.starts_with?”!”)
end

# muda a mensagem

def replace_message(attr, msg)

# se mensagem veio com {?}, agrega o nome do campo no meio do texto

if msg =~ /{?}/
msg.gsub(/{?}/, attr.to_s.humanize)
elsif msg.starts_with?(“!”) # se tiver ! no começo, remove
msg.from(1)
else
msg
end
end

def add_on_blank(attributes, msg = @@default_error_messages[:blank])
for attr in [attributes].flatten
value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s]

# se mensagem veio com {?}, agrega o nome do campo no meio do texto

if replace_message?(msg)
add(:base, replace_message(attr, msg)) if value.blank?
else
add(attr, msg) if value.blank? # fluxo normal
end
end
end
end
end[/source]
Não vou entrar em detalhes sobre o que o código faz (cabe a você analisar), mas basicamente eu verifico se o texto passado no :message possui:

  1. {?} em algum lugar do texto.
  2. Ou começa com ! (exclamação)

No primeiro caso, simplesmente subistituimos a string “{?}” pelo nome da coluna. O que nos permite criar algo assim: “O campo ‘{?}’ deve ser preenchido”.

No segundo caso, o código verifica se a mensagem começa com o símbolo de exclamação (!). Se sim, deixa a mensagem exatamente como está, ignorando completamente o nome da coluna.

Sendo assim, o código dado como exemplo acima poderia ficar assim:
[source:ruby]validates_presence_of :title,
:message => “!O campo ‘Título’ deve ser preenchido”[/source]
E o resultado na sua página seria:

  • O campo ‘Título’ deve ser preenchido

Este é apenas um exemplo de como podemos alterar o Rails de forma simples para nossas necessidades.


4 Comentários


  1. Tô vendo uma eclosão de um codificador ruby…

  2. comgo ocorre o erro de sintaxe de expressao regular:

    /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’: /home/jake/workspace/rails/sgh/lib/humanize_carlos_brando.rb:16: invalid regular expression; there’s no previous pattern, to which ‘{‘ would define cardinality at 1: /{?}/ (SyntaxError)

  3. o erro ocorre na expressão regular neste método :

    # true se a mensagem for alterável
    def replace_message?(msg)
    (msg =~ /{?}/) || (msg.starts_with?”!”)
    end

    poderias ajudar?

  4. Jake, eu aconselho que você use o novo recurso de i18n em seu projeto. Esta dica é muito antiga (2007) e não fazemos mais desta forma.

Deixe um comentário