Design Pattern. Decorator


If your views contains many if blocks logic or you have a lot of helpers methods - use Decorator Pattern with Draper gem


#/app/controllers/cars_controller.rb
class CarsController < ApplicationController
 def show
   @car = Car.find(params[:id])
 end
end

#/app/views/cars/show.html.haml
- content_for :header do
  %title
    - if @car.title_for_head
      = "#{ @car.title_for_head } | #{t('beautiful_cars')}"
    - else
      = t('beautiful_cars')
  - if @car.description_for_head
    %meta{:content => "#{#{@car.description_for_head}}", :name => "description"}/
- if @car.image
  = image_tag @car.image.url
- else
  = image_tag 'no-images.png'
%h1
  = t('brand')
  - if @car.brand
    = @car.brand
  - else
    = t('undefined')
%p
  = t('model')
  - if @car.model
    = @car.model
  - else
    = t('undefined')
%p
  = t('notes')
  - if @car.notes
    = @car.notes
  - else
    = t('undefined')
%p
  = t('owner')
  - if @car.owner
    = @car.owner
  - else
    = t('undefined')
%p
  = t('city')
  - if @car.city
    = @car.city
  - else
    = t('undefined')
%p
  = t('owner_phone')
  - if @car.phone
    = @car.phone
  - else
    = t('undefined')
%p
  = t('state')
  - if @car.used
    = t('used')
  - else
    = t('new')
%p
  = t('date')
  = @car.created_at.strftime("%B %e, %Y")



That code transformed to next example

#/app/controllers/cars_controller.rb
class CarsController < ApplicationController
 def show
   @car = Car.find(params[:id]).decorate
 end
end

#/app/decorators/car_decorator.rb
class CarDecorator < Draper::Decorator
 delegate_all
 def meta_title
   result =
     if object.title_for_head
       "#{ object.title_for_head } | #{I18n.t('beautiful_cars')}"
     else
       t('beautiful_cars')
     end
   h.content_tag :title, result
 end

 def meta_description
   if object.description_for_head
     h.content_tag :meta, nil ,content: object.description_for_head
   end
 end

 def image
   result = object.image.url.present? ? object.image.url : 'no-images.png'
   h.image_tag result
 end

 def brand
   get_info object.brand
 end

 def model
   get_info object.model
 end

 def notes
   get_info object.notes
 end

 def owner
   get_info object.owner
 end

 def city
   get_info object.city
 end

 def owner_phone
   get_info object.phone
 end

 def state
   object.used ? I18n.t('used') : I18n.t('new')
 end

 def created_at
   object.created_at.strftime("%B %e, %Y")
 end

 private

 def get_info value
   value.present? ? value : t('undefined')
 end
end

\#/app/views/cars/show.html.erb
- content_for :header do
  = @car.meta_title
  = @car.meta_description
​
= @car.image
%h1
  = t('brand')
  = @car.brand
%p
  = t('model')
  = @car.model
%p
  = t('notes')
  = @car.notes
%p
  = t('owner')
  = @car.owner
%p
  = t('city')
  = @car.city
%p
  = t('owner_phone')
  = @car.phone
%p
  = t('state')
  = @car.state
%p
  = t('date')
  = @car.created_at

(c) https://www.sitepoint.com/

Comments