Posted on abril 2, 2023
Rails Helpers – o que são e para que servem?
Já aconteceu com vocês de utilizarem um conceito na linguagem de programação da sua preferência mas não saberem exatamente porque o estão utilizando? Ou para que precisamente ele funciona? Isso aconteceu comigo recentemente, quando me caiu uma tarefa nas mãos de refatorar o código de outra pessoa: eu não entendia muito bem o que eram os modules
do Rails nem para que serviam os Helpers
. Por isso, tirei um tempinho para estudar isso e preparei esse resumão sobre o que são e para que servem os Helpers do Rails!
ℹ️ This post is available in English at my dev.to 💫
Organizando o baile
Nesse post, pretendo discorrer sobre, na seguinte ordem:
- Uma explicação geral sobre o que são os métodos Helpers do Rails e quais são as melhores práticas associadas à eles
- Abordar mais detalhes sobre os Modules do Ruby e qual é a sua importância dentro da linguagem
- Tocar um pouco no assunto de Composição vs. Herança, que é sempre bom ter fresco na memória
O que são Helpers no Rails?
Os Helpers são métodos majoritariamente usados para compartilhar código reutilizável entre as views do seu projeto. É importante ressaltar que os Helpers não precisam necessariamente serem criados pelos desenvolvedores: já existem alguns métodos nativos do próprio Rails para facilitar a nossa vida.
Exemplos de Helpers nativos do Rails:
time_ago_in_words(Time.now) # "less than a minute" number_to_human(10_000) # "10 Thousand"
Os métodos Helpers são muito importantes também, quando criados pelos próprios programadores, para aplicar o princípio DRY dentro do código do projeto, uma vez que você está condensando uma parte da lógica em um único lugar, em vez de tê-la espalhada por vários pontos do código.
Escrevendo seus próprios Helpers
Existe um diretório específico para você criar seus próprios Helpers no Rails, que é o
. Dentro dessa pasta, você precisa criar um novo arquivo e, dentro de um app/helpers
module
, desenvolver o que precisa. Tudo o que estiver ali automaticamente se torna visível para as views
do seu projeto.
Um exemplo: fomos até o app/helpers
e criamos o arquivo usuario_helper.rb
, que vai conter todos os nossos helpers relacionados ao usuário. Lá dentro, construiremos o seguinte module
:
module UsuarioHelper def formatar_nome(usuario) if usuario.genero== "M" "Sr. #{usuario.nome}" else "Sra. #{usuario.nome}" end end end
Existe também uma opção genérica, caso a sua aplicação seja pequena e você precise de poucos Helpers, por exemplo, que é deixar tudo dentro do ApplicationHelper
, que um module base do Rails prontinho para receber futuros helpers desenvolvidos por você.
Melhores práticas envolvendo Helpers
Quando usar e/ou criar um helper?
Sempre que você tiver lógica reutilizável que produz código HTML. Em grande parte das vezes, esses códigos estão relacionados à formatação de strings ou elementos das views
que são condicionais. É interessante que você encapsule essa lógica dentro de um helper para que ela não fique espalhada e repetida por toda a sua aplicação.
Use a abuse dos parâmetros
É uma maneira de deixar claro desde o princípio o que o seu método precisa e você não corre o risco de ter qualquer erro relacionado a missing variables enquanto está lidando com informações dentro do seu helper.
Tente não utilizar helpers nos Controllers
Algumas pessoas programadoras são da opinião que podem existir Controller Helpers, ou seja, helpers que estão mais preocupados com a lógica do que com a apresentação da sua aplicação. E também é possível utilizar os helpers das views diretamente nos controllers, apenas invocando-os com o objeto helpers
. Um exemplo:
class UsuariosController def index helpers.time_ago_in_words(Time.now) end end
O RubyGuides pede alguma cautela na hora de fazer isso pois pode ser considerado um problema de design, sugerindo o uso de um objeto Ruby em seu lugar, apesar de não dar mais detalhes do porquê. Também achei que vale deixar aqui o alerta e, na dúvida, deixe os helpers somente para as views, OK?
O que são Modules do Ruby?
Durante esse artigo, eu falei muito sobre os modules do Ruby e o quão importante eles são na hora de escrever os helpers. E aí eu percebi que eu não sabia o que caralhos era um module do Ruby. Portanto, fui procurar e trago aqui esse extra importante sobre o que é e para que serve essa keywordzinha tão útil.
Um module é um container do Ruby, que serve para guardar métodos, variáveis e constantes. É similar a uma classe, mas ao contrário desta, um module não pode ser instanciado. Seria similar o conceito do static no .NET.
Os modules tem dois objetivos principais dentro do Ruby:
- Criar um namespace, ou seja, agregar objetos logicamente relacionados, evitando também conflitos de nomes
- Facilitar a composição das coisas dentro da sua aplicação
O Ruby como linguagem de programação não tem herança múltipla. Logo, para que possamos manter o código escalável e manutenível à longo prazo, é necessário aplicar o princípio de Composição Sobre Herança. E, para nossa alegria, o Ruby nos facilita o uso de composição por aplicar algo que se chama Mixing Facility (em uma tradução livre: Facilidade de Mixagem).
A Mixing Facility nada mais é do que um module ser incluído por outro, ou até mesmo por outra classe, através de keywords como include
, prepend
ou extend
.
Composição versus Herança
Ah, a velha questão daqueles que programam orientados à objeto e ao salário… Presente desde o mais tenro aprendizado até o mais dinossáurico dos sêniors. Justamente por ser tão presente no nosso dia a dia, acho importante trazer mais uma vez a definição desses dois conceitos, visto que já está explicado logo ali em cima porque um deles é mais importante para o Rails. Deixo também um link do DevMedia com um artigo bem explicadinho sobre a importância de cada um deles e qual utilizar (spoiler: na maioria das vezes, não é Herança).
Herança
A Herança, dentro da programação, é definida pela existência de uma classe pai (ou classe base ou superclasse) e uma classe filha (ou subclasse), e é considerada uma ferramenta básica de extensão e reuso de funcionalidades. Nesse princípio, falamos muito de generalização de conceitos: obtemos similaridades entre classes e estas são colocadas na classe pai. Toda e qualquer especificidade de negócio é colocada na classe filha.
Dentro desse conceito, temos um forte acoplamento entre classes, pois uma vai dependendo da outra durante o percurso do sistema.
Composição
Na Composição, nós definimos alguns pequenos comportamentos que irão existir entre as classes, que serão padronizados. E conforme nossas classes vão surgindo e se modificando, vamos compondo comportamentos mais complexos com essas pequenas unidades de comportamentos já previamente desenhados e testados. Ou seja, aqui o forte é o encapsulamento da lógica, o que é sempre uma boa prática.
ღ Revisões e correções
30 de maio de 2023 – corrigi algumas passagens do texto que diziam que os modules
pertenciam ao Rails, quando de fato pertencem ao Ruby em si. Obrigada Sérgio Ribeiro pelo aviso! 😀
✔ Links consultados
♥ RubyGuides: How to Use Rails Helpers (Complete Guide) – por Jesus Castello
★ Helper Methods – por Damely Tineo
♥ Modules in Ruby: Part I – por RubyCademy
★ DevMedia: Herança versus Composição: qual utilizar? – por Higor
Acessei os links pela última vez dia 02 de abril de 2023.
♦ Posts relacionados
✪ Uma gem na roda: syntax_suggest
✪ Um ambiente de desenvolvimento Rails com Docker
✉ Recadinhos
Gostou do texto? Tem algo a adicionar? Alguma crítica construtiva? Feedbacks? Sugestões? Pedidos? Fique à vontade para me contatar via email (oli.pmatt@gmail.com), Twitter (@oliviamattiazzo), LinkedIn (/oliviamattiazzo) ou pela caixa de comentários aqui embaixo! Vai ser um prazer conversar contigo! ✨