Ricerca…


Osservazioni

Il pattern Decorator consente di aggiungere o modificare il comportamento degli oggetti in modo situazionale senza influire sull'oggetto di base.

Questo può essere ottenuto attraverso il semplice Ruby usando lo stdlib, o tramite gemme popolari come Draper .

Decorazione di un modello con SimpleDelegator

La maggior parte degli sviluppatori di Rails inizia modificando le informazioni sul modello all'interno del modello stesso:

<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>

Per i modelli con molti dati, questo può diventare rapidamente ingombrante e portare alla logica di copia-incolla da un modello all'altro.

Questo esempio utilizza SimpleDelegator dallo stdlib.

Tutte le richieste a un oggetto SimpleDelegator vengono passate all'oggetto padre per impostazione predefinita. È possibile sovrascrivere qualsiasi metodo con la logica di presentazione oppure è possibile aggiungere nuovi metodi specifici per questa vista.

SimpleDelegator fornisce due metodi: __setobj__ per impostare a quale oggetto viene delegato e __getobj__ per ottenere quell'oggetto.

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

Alcuni decoratori si affidano alla magia per collegare questo comportamento, ma è possibile rendere più ovvio da dove proviene la logica di presentazione inizializzando l'oggetto sulla pagina.

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

Passando un riferimento all'oggetto vista nel decoratore, possiamo ancora accedere a tutti gli altri helper della vista mentre si costruisce la logica di presentazione senza doverlo includere.

Ora il modello di visualizzazione riguarda solo l'inserimento di dati nella pagina ed è molto più chiaro.

Decorare un modello usando Draper

Draper abbina automaticamente i modelli con i loro decoratori per convenzione.

# 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

Data una variabile @user che contiene un oggetto ActiveRecord, puoi accedere al decoratore chiamando #decorate su @user o specificando la classe Draper se vuoi essere specifico.

<% 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow