Helpers + Presenters e Decorators

Tutoriais - 25/Set/2019 - por Campus Code

Este artigo é uma continuação do texto Presenters e Decorators em Ruby em que foi usado o SimpleDelegator. Se você conhece esses padrões e já utilizou SimpleDelegator ou outra estratégia para delegar métodos em classes, fique à vontade para continuar, caso contrário, recomendamos a leitura da primeira parte. Aqui falaremos, brevemente, como usar helpers com Presenters e Decorators em aplicações Ruby on Rails.

No artigo anterior, descrevemos um exemplo de Presenter para uma aplicação que simula o sistema de uma locadora de veículos e nele a classe Rental representa uma locação. Ela possui um cliente (customer), um preço (price) e um status (status):

class Rental
 attr_accessor :status, :customer, :price

 def initialize(status, customer, price)
   @status = status
   @customer = customer
   @price = price
 end
end

No código do RentalPresenter sobrescrevemos o método status, implementamos display e utilizamos o SimpleDelegator para delegar outros métodos à classe Rental:

class RentalPresenter < SimpleDelegator
 def status
   "A locação está com status: #{super} "
 end

 def display
   "O cliente #{customer}, tem uma locação no valor de #{price}."
 end
end

Agora, podemos melhorar um pouco o código do Presenter para que seus métodos retornem valores preparados para as views da sua aplicação. Para facilitar esse trabalho, podemos incluir um método privado que adicione os helpers de ApplicationController à sua classe.

class RentalPresenter < SimpleDelegator
 def status
   "A locação está com status: #{super} "
 end

 def display
   "O cliente #{customer}, tem uma locação no valor de #{price}."
 end

 private

 def helper
   ApplicationController.helpers
 end
end

Dessa forma, os helpers como link_to e content_tag ficam disponíveis no Presenter. Agora podemos adicionar um badge ao status, melhorando sua visualização.

class RentalPresenter < SimpleDelegator
 def status
   helper.content_tag(:span, class: 'badge badge-success') do
     "#{super}"
   end
 end

 def display
   "O cliente #{customer}, tem uma locação no valor de #{price}."
 end

 private

 def helper
   ApplicationController.helpers
 end
end

Na view da sua aplicação, desde que você exponha um objeto de RentalPresenter pelo RentalsController, você pode chamar o método status em uma locação e ele construirá para você o badge no HTML.

# RentalsController.rb

def show                                                                       
  rental = Rental.find(params[:id])                                            
  @rental = RentalPresenter.new(rental)                               
end
# rentals/show.html.erb

<h1>Locação</h1>
<%= @rental.status %>
Campus Code