Entendendo Struct em Ruby on Rails
O Ruby é conhecido por sua sintaxe elegante e flexibilidade, permitindo que os desenvolvedores criem códigos concisos e legíveis. Um dos recursos menos conhecidos, mas poderosos no Ruby, é o Struct
, uma classe embutida que oferece uma maneira simples de agrupar atributos relacionados sem a sobrecarga de definir uma classe completa. Embora não seja tão comumente utilizado quanto os modelos ActiveRecord ou POROs (Plain Old Ruby Objects), o Struct
pode ser extremamente útil em aplicações Rails em certos cenários.
O que é Struct?
Struct
em Ruby é um atalho para definir classes simples que agrupam alguns atributos, fornecendo métodos getters e setters para esses atributos automaticamente. Ele cria uma nova classe que se comporta como um objeto leve, com os atributos que você define ao inicializar.
Por exemplo, digamos que você queira criar um objeto simples para representar um ponto em um espaço 2D com coordenadas x
e y
. Você pode fazer isso da seguinte forma:
Point = Struct.new(:x, :y)
point = Point.new(10, 20)
puts point.x # Saída: 10
puts point.y # Saída: 20
Aqui, Struct.new
gera uma classe Point
com os atributos x
e y
, além de métodos para obter e definir esses valores. Nesse caso, o Struct
economiza o trabalho de definir explicitamente uma classe com um inicializador e acessores para esses atributos.
Quando Usar Struct no Rails
Embora você trabalhe principalmente com modelos ActiveRecord e objetos de serviço no Rails, o Struct
tem seu lugar para objetos simples e leves que não precisam das capacidades completas de um modelo. Aqui estão alguns casos onde o Struct
pode ser útil:
1. Armazenamento Temporário de Dados
Quando você precisa armazenar dados temporariamente, mas não deseja criar um modelo ou classe completa, o Struct
é ideal. Isso é especialmente verdadeiro quando os dados não precisam persistir no banco de dados, existindo apenas durante uma requisição ou sessão.
Exemplo: Imagine que você está trabalhando em um sistema de reservas e deseja criar um objeto de resumo de viagem sem salvá-lo no banco de dados.
TripSummary = Struct.new(:destination, :duration, :price)
summary = TripSummary.new("Havaí", "7 dias", 1500)
puts summary.destination # Saída: Havaí
puts summary.price # Saída: 1500
2. Respostas de API
Se a sua aplicação Rails interage com APIs externas, você pode receber respostas JSON que se mapeiam para dados estruturados. Você pode facilmente envolver essas respostas em um Struct
para tornar o manuseio delas mais organizado e legível.
Exemplo: Suponha que você esteja trabalhando com uma API que retorna dados climáticos:
WeatherData = Struct.new(:temperature, :humidity, :wind_speed)
response = { temperature: 75, humidity: 65, wind_speed: 10 }
weather = WeatherData.new(response[:temperature], response[:humidity], response[:wind_speed])
puts weather.temperature # Saída: 75
puts weather.humidity # Saída: 65
Usar Struct
aqui ajuda a encapsular a resposta em um objeto claro e específico para o domínio.
3. Objetos de Formulário
No Rails, objetos de formulário são frequentemente usados para lidar com formulários complexos que envolvem múltiplos modelos ou atributos que não são do banco de dados. Em vez de criar uma classe nova para cada formulário, você pode usar Struct
para reunir atributos temporariamente.
Exemplo: Suponha que você esteja construindo um processo de inscrição com várias etapas. Em uma etapa, você precisa coletar informações pessoais:
PersonalInfo = Struct.new(:first_name, :last_name, :email)
info = PersonalInfo.new("John", "Doe", "john.doe@example.com")
Com isso, você pode passar o objeto PersonalInfo
, tornando o processo do formulário mais gerenciável.
Melhorando o Struct com Métodos Personalizados
Uma das grandes vantagens do Struct
é que ele se comporta como uma classe Ruby regular, então você pode adicionar métodos personalizados a ele. Isso permite encapsular lógica relacionada ao seu objeto Struct
.
Exemplo: Vamos melhorar o exemplo do TripSummary
adicionando um método para calcular o custo total com impostos.
TripSummary = Struct.new(:destination, :duration, :price) do
def total_cost_with_tax(tax_rate)
price + (price * tax_rate)
end
end
summary = TripSummary.new("Havaí", "7 dias", 1500)
puts summary.total_cost_with_tax(0.10) # Saída: 1650
Isso permite manter a lógica relacionada dentro do objeto, assim como faria com uma classe completa.
Comparando Struct com POROs e Modelos
Embora o Struct
seja uma ferramenta útil, é importante saber quando não usá-lo. Aqui está uma comparação rápida entre Struct
e outros objetos comuns no Rails:
Aspecto | Struct | PORO | Modelo ActiveRecord |
---|---|---|---|
Complexidade | Leve, simples | Pode ser leve ou complexo | ORM completo |
Persistência | Sem interação com banco | Sem interação com banco | Interage com banco |
Personalização | Fácil de definir métodos | Totalmente personalizável | Totalmente personalizável |
Caso de Uso | Dados temporários, API, formulários | Lógica de negócios, objetos de serviço | Dados persistentes, lógica de negócios |
O Struct
em Ruby on Rails é uma maneira versátil e eficiente de lidar com estruturas de dados simples sem a necessidade de classes completas ou modelos ActiveRecord. É perfeito para tarefas leves, como armazenamento temporário de dados, manipulação de respostas de API ou encapsulamento de atributos de formulário. Usando Struct
no contexto certo, você pode simplificar seu código e torná-lo mais legível, evitando complexidade desnecessária.