Organizando as Expressões Regulares No Rails

No dia a dia sempre necessitamos dos super poderes das Expressões Regulares para validações de formulários, replaces em textos e tantas outras coisas mais, alguns patterns raramente mudam de um projeto para outro, o pattern para validar e-mails é um exemplo.

Pensando nisso e aproveitando a estrutura do Rails que já possui a pasta /lib para armazenar nossos códigos customizados, criei um module “ER” para ir colecionando os patterns rotineiros.

Neste post estou mostrando uma solução que encontrei pois ainda desconheço se o Rails possui alguma convenção para essa tarefa.

Vamos ver a ideia!

Na pasta /lib criei um arquivo er.rb que será nosso “repositório de ERs”.

ruby
1
2
3
4
5
6
7
8
9
10
11
12
module ER
  # Pattern para validação de e-mail
  EMAIL = /^[^@][\w.-]+@[\w.-]+[.][a-z]{2,4}$/i
  # Pattern para validação de data no padrão 99/99/9999
  DATE = /^(([012][0-9])|(3[01]))\/(0[1-9]|1[012])\/\d{4}$/
  # Pattern para validação de data no padrão 9999-99-99
  DATE_DB = /^\d{4}-(0[1-9]|1[012])-(([012][0-9])|(3[01]))$/
  # Pattern para validação de horas sem os segungos no padrão 99:99
  TIME_H_M = /^(([01]\d)|(2[0-3])):([0-5]\d)$/
  # Pattern para validação de urls, permitido os protocolos http e https
  URL = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix
end

Utilizando

Para exemplificar, vamos validar um model User.

ruby
1
2
3
4
5
require 'er'
class User < ActiveRecord::Base
  attr_accessible :email, :full_name
  validates :email, presence:true,  format:{with: ER::EMAIL}
end

Perceberam a chamada do pattern? :P

Para validação em front-end utilizando o atributo pattern do HTML5, podemos reaproveitar nossos patterns, só que precisamos de um passo a mais devido o padrão ser ER crua sem estar contida em “//” (barras).

Criei então um Help para fazer essa tarefa e as View continuarem fazendo apenas seu papel. No arquivo app/helpers/application_helper.rb incluir:

ruby
1
2
3
4
5
6
7
def er_for_html(er)
  begin
    ER.const_get(er.upcase.to_sym).source
  rescue NameError => exc
    "A expressao solicitada nao existe"
  end
end

Notem que usei Module#const_get para pegar a referência da constante informado e no fim o Regexp#source que retorna a string original que está envolvida por “//”
Ficando no formulário:

ruby
1
<%= f.text_field(:email, :class => :span3, :pattern => er_for_html("email"), :type => :email, :required => true, :title => "E-mail" ) %>

Concluíndo

É isso ai, a intenção é só para mostar uma possibilidade de organizar as coisas, claro que deve possuir outras, dessa forma, aceito sugestões e dicas. :)

Para uma consulta rápida sobre metacaracteres o Aurélio disponibiliza um guia rápido http://piazinho.com.br/download/expressoes-regulares-3-tabelas.pdf.
Para se aprofundar, leia o livro Expressões Regulares - Uma abordagem divertida.

Commentários