Action View no Rails: Dominando Templates, Formulários e Helpers
Action View no Rails: Dominando Templates, Formulários e Helpers
Action View representa a camada de visualização da nossa trilogia MVC no Rails, encapsulando toda a funcionalidade necessária para renderizar templates e gerar HTML, XML ou JavaScript de volta para o usuário. Neste tutorial prático, vamos explorar desde conceitos fundamentais até técnicas avançadas de organização e manutenção de views.
Templates: O Coração das Views
Para dominar o Action View, precisamos entender três aspectos fundamentais dos templates: onde eles ficam, o ambiente em que executam e o que contêm.
Organização e Estrutura de Templates
O método render() espera encontrar templates no diretório app/views da aplicação atual. A convenção estabelece um subdiretório separado para as views de cada controller:
# Estrutura de diretórios para templates
app/views/
produtos/
index.html.erb
show.html.erb
edit.html.erb
loja/
index.html.erb
carrinho.html.erb
# Renderização flexível de templates
render(action: 'nome_acao_falsa')
render(template: 'controller/nome')
render(file: 'diretorio/template')
Ambiente de Execução dos Templates
Templates executam em um ambiente rico que fornece acesso completo às informações configuradas pelo controller:
<!-- Template de debug para desenvolvimento -->
<h4>Sessão</h4> <%= debug(session) %>
<h4>Parâmetros</h4> <%= debug(params) %>
<h4>Resposta</h4> <%= debug(response) %>
Formulários: Coletando Dados dos Usuários
O Rails oferece uma coleção abrangente de helpers para gerar formulários HTML de forma elegante e funcional. Vamos construir um formulário completo que demonstra os principais tipos de entrada:
<%= form_for(:modelo) do |formulario| %>
<p>
<%= formulario.label :entrada %>
<%= formulario.text_field :entrada, :placeholder => 'Digite o texto aqui...' %>
</p>
<p>
<%= formulario.label :endereco %>
<%= formulario.text_area :endereco, :rows => 3, :cols => 40 %>
</p>
<!-- Botões de rádio para seleção única -->
<p>
<%= formulario.label :cor %>:
<%= formulario.radio_button :cor, 'vermelho' %>
<%= formulario.label :vermelho %>
<%= formulario.radio_button :cor, 'amarelo' %>
<%= formulario.label :amarelo %>
</p>
<!-- Checkboxes para seleção múltipla -->
<p>
<%= formulario.label 'condimento' %>:
<%= formulario.check_box :ketchup %>
<%= formulario.label :ketchup %>
<%= formulario.check_box :mostarda %>
<%= formulario.label :mostarda %>
</p>
<% end %>
Upload de Arquivos: Implementação Completa
Para implementar upload de arquivos, precisamos configurar o formulário, model e controller adequadamente. Vamos criar um sistema de upload de imagens:
# Migration para tabela de imagens
class CreateImagens < ActiveRecord::Migration
def change
create_table :imagens do |t|
t.string :comentario
t.string :nome
t.string :tipo_conteudo
t.binary :dados, :limit => 1.megabyte
end
end
end
# Model com validação e processamento de upload
class Imagem < ActiveRecord::Base
validates_format_of :tipo_conteudo,
with: /\Aimage/,
message: "deve ser uma imagem"
def imagem_enviada=(campo_imagem)
self.nome = extrair_nome_base(campo_imagem.original_filename)
self.tipo_conteudo = campo_imagem.content_type.chomp
self.dados = campo_imagem.read
end
private
def extrair_nome_base(nome_arquivo)
File.basename(nome_arquivo).gsub(/[^\w._-]/, '')
end
end
O formulário de upload requer configuração específica para multipart/form-data:
<%= form_for(:imagem,
url: {action: 'salvar'},
html: {multipart: true}) do |form| %>
Comentário: <%= form.text_field("comentario") %><br/>
Envie sua imagem: <%= form.file_field("imagem_enviada") %><br/>
<%= submit_tag("Enviar arquivo") %>
<% end %>
Helpers: Estendendo a Funcionalidade das Views
Helpers são módulos que encapsulam métodos de saída, mantendo as views limpas e organizadas. O Rails oferece helpers integrados poderosos e permite criar helpers personalizados.
Helpers de Formatação Integrados
<!-- Helpers de tempo e data -->
<%= distance_of_time_in_words(Time.now, Time.local(2024, 12, 25)) %>
# => "aproximadamente 2 meses"
<%= time_ago_in_words(Time.local(2024, 10, 15)) %>
# => "há 5 meses"
<!-- Helpers de formatação numérica -->
<%= number_to_currency(1234.56) %>
# => "R$ 1.234,56"
<%= number_to_currency(234.56, unit: "US$", precision: 0) %>
# => "US$ 235"
<%= number_to_human_size(123456) %>
# => "120,6 KB"
<%= number_to_percentage(66.66666, precision: 1) %>
# => "66,7%"
Helpers de Links e Navegação
<!-- Link básico -->
<%= link_to "Adicionar Comentário", new_comentarios_path %>
<!-- Link com confirmação e método HTTP específico -->
<%= link_to "Deletar", produto_path(@produto),
method: :delete,
data: { confirm: 'Tem certeza?' },
class: "perigoso" %>
<!-- Menu com link condicional -->
<ul>
<% %w{ criar listar editar salvar }.each do |acao| %>
<li>
<%= link_to_unless_current(acao.capitalize, action: acao) %>
</li>
<% end %>
</ul>
<!-- Link de email com obfuscação -->
<%= mail_to("suporte@minhaempresa.com.br", "Contatar Suporte",
subject: "Pergunta de suporte de #{@usuario.nome}",
encode: "javascript") %>
Criando Helpers Personalizados
# app/helpers/loja_helper.rb
module LojaHelper
def titulo_pagina
@titulo_pagina || "Loja Pragmática"
end
def formatar_preco_brasileiro(valor)
number_to_currency(valor, unit: "R$ ", separator: ",", delimiter: ".")
end
def status_pedido_estilizado(status)
classes_css = case status
when 'pendente'
'status-pendente amarelo'
when 'processando'
'status-processando azul'
when 'concluido'
'status-concluido verde'
else
'status-desconhecido cinza'
end
content_tag(:span, status.capitalize, class: classes_css)
end
end
Layouts e Partials: Organizando a Estrutura
Layouts e partials são fundamentais para manter o código DRY (Don't Repeat Yourself) e facilitar a manutenção das views.
Estrutura de Layouts Dinâmicos
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<title><%= @titulo || "Minha Aplicação Rails" %></title>
<%= stylesheet_link_tag 'application' %>
<%= javascript_importmap_tags %>
<!-- Conteúdo específico da página -->
<%= yield :head %>
</head>
<body>
<header>
<h1><%= @titulo %></h1>
</header>
<div class="container">
<main>
<%= yield %>
</main>
<aside class="sidebar">
<p>Conteúdo regular da sidebar</p>
<div class="sidebar-especifica">
<%= yield :sidebar %>
</div>
</aside>
</div>
</body>
</html>
O template individual pode definir conteúdo específico para diferentes seções:
<% @titulo = "Minha Página Especializada" %>
<% content_for(:head) do %>
<meta name="description" content="Página específica para SEO">
<% end %>
<% content_for(:sidebar) do %>
<ul>
<li>Menu específico da página</li>
<li>Item dinâmico: <%= @dados_dinamicos %></li>
</ul>
<% end %>
<p>Aqui está o conteúdo regular que aparecerá na página renderizada pelo template</p>
Partials com Coleções
Partials são especialmente poderosos quando trabalham com coleções de dados. Vamos ver um exemplo prático:
<!-- app/views/produtos/_produto.html.erb -->
<div class="produto">
<div class="cabecalho-produto">
<h3>
<%= link_to produto.nome, produto %>
<span class="contador">#<%= produto_counter + 1 %></span>
</h3>
</div>
<div class="corpo-produto">
<p><%= truncate(produto.descricao, length: 100) %></p>
<div class="preco"><%= formatar_preco_brasileiro(produto.preco) %></div>
</div>
</div>
O template principal renderiza a coleção com espaçador personalizado:
<!-- Renderização com coleção e espaçador -->
<div class="catalogo-produtos">
<%= render(partial: "produto",
collection: @lista_produtos,
spacer_template: "divisor") %>
</div>
<!-- Partial compartilhado -->
<%= render("shared/cabecalho", locals: {titulo: @artigo.titulo}) %>
Boas Práticas e Considerações de Performance
Para maximizar a eficiência e manutenibilidade do seu código Action View, considere estas práticas essenciais:
- Minimize lógica nas views: Mantenha templates focados na apresentação, delegando lógica complexa para helpers ou modelos.
- Use partials estrategicamente: Quebre views grandes em partials reutilizáveis, especialmente para componentes repetidos.
- Aproveite helpers integrados: O Rails oferece helpers otimizados para formatação, links e internacionalização.
- Organize layouts hierarquicamente: Use layouts específicos de controller quando necessário, mantendo um layout de aplicação comum.
- Teste helpers personalizados: Helpers são fáceis de testar isoladamente, ao contrário de código embarcado em views.
Conclusão
Action View oferece um ecossistema completo para construção de interfaces robustas e maintíveis. Desde templates básicos até sistemas complexos de layouts e partials, passando por formulários avançados e helpers personalizados, dominamos as ferramentas essenciais para criar aplicações Rails profissionais. A arquitetura MVC do Rails brilha especialmente na camada de view, onde a separação clara de responsabilidades e as convenções inteligentes aceleram significativamente o desenvolvimento.
Com este conhecimento sólido de Action View, você está preparado para construir interfaces de usuário elegantes que não apenas funcionam perfeitamente, mas também são fáceis de manter e evoluir ao longo do tempo.
Nenhum comentário:
Postar um comentário