Buscar..


Observaciones

El patrón Decorator le permite agregar o modificar el comportamiento de los objetos de una manera coyuntural sin afectar el objeto base.

Esto se puede lograr a través de Ruby usando el stdlib, o por medio de gemas populares como Draper .

Decorar un modelo utilizando SimpleDelegator

La mayoría de los desarrolladores de Rails comienzan modificando la información de su modelo dentro de la propia plantilla:

<h1><%= "#{ @user.first_name } #{ @user.last_name }" %></h1>
<h3>joined: <%= @user.created_at.in_time_zone(current_user.timezone).strftime("%A, %d %b %Y %l:%M %p") %></h3>

Para modelos con una gran cantidad de datos, esto puede volverse engorroso rápidamente y llevar a copiar y pegar la lógica de una plantilla a otra.

Este ejemplo utiliza SimpleDelegator de la stdlib.

Todas las solicitudes a un objeto SimpleDelegator se pasan al objeto principal de forma predeterminada. Puede anular cualquier método con lógica de presentación, o puede agregar nuevos métodos que sean específicos para esta vista.

SimpleDelegator proporciona dos métodos: __setobj__ para establecer a qué objeto se está delegando, y __getobj__ para obtener ese objeto.

class UserDecorator < SimpleDelegator
  attr_reader :view
  def initialize(user, view)
    __setobj__ @user
    @view = view
  end

  # new methods can call methods on the parent implicitly
  def full_name
    "#{ first_name } #{ last_name }"
  end

  # however, if you're overriding an existing method you need
  # to use __getobj__
  def created_at
    Time.use_zone(view.current_user.timezone) do
      __getobj__.created_at.strftime("%A, %d %b %Y %l:%M %p")
    end
  end
end

Algunos decoradores confían en la magia para conectar este comportamiento, pero puede hacer que sea más obvio de dónde proviene la lógica de presentación al inicializar el objeto en la página.

<% user = UserDecorator.new(@user, self) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>

Al pasar una referencia al objeto de vista al decorador, aún podemos acceder al resto de los asistentes de vista mientras construimos la lógica de presentación sin tener que incluirlo.

Ahora, la plantilla de vista solo se ocupa de insertar datos en la página, y es mucho más claro.

Decorando un modelo usando Draper

Draper combina automáticamente los modelos con sus decoradores por convención.

# app/decorators/user_decorator.rb
class UserDecorator < Draper::Decorator
  def full_name
    "#{object.first_name} #{object.last_name}"
  end

  def created_at
    Time.use_zone(h.current_user.timezone) do
      object.created_at.strftime("%A, %d %b %Y %l:%M %p")
    end
  end
end

Dada una variable @user que contiene un objeto ActiveRecord, puede acceder a su decorador llamando a #decorate en @user , o especificando la clase Draper si desea ser específico.

<% user = @user.decorate %><!-- OR -->
<% user = UserDecorator.decorate(@user) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow