October 1st, 2007Evite repetição de código no Ruby On Rails
Um dos princípios por trás do Ruby On Rails é o DRY (Don’t Repeat Yourself), ou seja, não se repita. Ele nos fornece muitos meios de se evitar repetições, e o que mais uso pra esse propósito são os filtros.
Filtros, no Rails, definem um método que será executado antes e/ou depois de cada página daquela classe. Então, nos nossos controllers, podemos usar os filtros para executar as mesmas tarefas rotineiras em todas as páginas sem ter que repetir aquele código dentro de cada action.
Definindo um filtro
Nós temos 3 tipos de filtro à disposição: before_filter, after_filter, e around_filter. O before_filter define um método que será executado antes de carregar cada página da nossa aplicação. O after_filter define um método que será executado depois de cada página da aplicação. E, por último, o around_filter define um método que será executado antes e depois de cada página.
Vejamos um exemplo de um controller simples que usa um filtro.
class ShoppingController < ActionController::Base before_filter :nosso_metodo #imagine aqui várias actions da aplicação private def nosso_metodo @mensagem = "Esta é uma mensagem" end end
No exemplo acima, temos o controller Shopping, e antes de cada página deste controller o método nosso_metodo é chamado, por ter sido definido no before_filter. O método, então, define uma mensagem qualquer que usamos apenas de exemplo.
Fazendo uma action ignorar um filtro
Em algumas situações, podemos ter um ou outra action dentro da nossa classe que não precisa que aquele filtro seja executado. Para isso, podemos fazer com que uma action deliberadamente “salte” um filtro, ignorando-o.
Ainda usando o exemplo anterior, se a gente quisesse criar uma action chamada salteadora que não precisa do filtro que definimos, faríamos assim:
def salteadora skip_filter :nosso_metodo end
Definindo condições para o filtro
Ainda melhor do que definir saltos de filtro nas classes é definir condições no próprio filtro. Podemos fazer o filtro ser executado apenas em certas actions, ou fazer com que ele apenas não seja executado em certas actions.
Para criarmos um filtro que será executado apenas em actions definidas por nós:
before_filter :nosso_metodo, :only => [:action1, :action2, :action3]
E podemos ir definindo quantas actions quisermos no campo only.
Agora, para que o filtro rode em todas as actions menos as definidas por nós, usaremos exceções.
before_filter :nosso_metodo, :except => [:action1, :action2]
Agora o método executaria em todas as páginas, exceto na action1 e na action2.
Onde usar os filtros
Se você leu isso tudo e não sabe muito bem onde ou por que precisaria dos filtros, vou dar um exemplo usando meu site feito em ruby, o emprestei.com.
O emprestei é um site onde as pessoas anotam seus empréstimos. Então, em todas as páginas do site, eu precisava exibir uma contagem atualizada de quantas coisas do usuário estão emprestadas. Se eu colocasse o código de contagem de empréstimos em todas as páginas eu estaria fazendo uma repetição desnecessária de código e ignorando o conceito de DRY do Rails.
Qual a solução? Eu criei um before_filter que chama o método common_tasks (tarefas rotineiras), e neste método eu coloquei o código de contagem de empréstimos. Pronto, agora eu tenho o código em um único lugar, mas que será executado em todas as páginas que o usuário entrar.
Neste mesmo filtro do emprestei eu também usei uma exceção. Havia uma página que não teria uma contagem de empréstimos, que é a página dos usuários que não estão logados no sistema. Para não tentar contar empréstimos de um usuário que não estava no sistema, adicionei um except no meu filtro.
Evite, sempre, repetição do mesmo código. Se o código está apenas em um lugar, é mais fácil corrigir os erros e realizar mudanças com maior rapidez. Afinal, no nosso ramo, existe uma máxima que é muito válida: tempo é dinheiro!
Se interessou? Compre agora mesmo um livro de Ruby on Rails com o menor preço!
Posts recomendados: