Recherche…


Remarques

Le motif Décorateur vous permet d'ajouter ou de modifier le comportement des objets de manière situationnelle sans affecter l'objet de base.

Cela peut être réalisé en utilisant Ruby en utilisant le stdlib, ou via des gemmes populaires telles que Draper .

Décorer un modèle en utilisant SimpleDelegator

La plupart des développeurs Rails commencent par modifier leurs informations de modèle dans le modèle même:

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

Pour les modèles avec beaucoup de données, cela peut rapidement devenir encombrant et conduire à une logique de copier-coller d'un modèle à un autre.

Cet exemple utilise SimpleDelegator partir du stdlib.

Toutes les demandes SimpleDelegator à un objet SimpleDelegator sont transmises à l'objet parent par défaut. Vous pouvez remplacer n'importe quelle méthode par la logique de présentation ou ajouter de nouvelles méthodes spécifiques à cette vue.

SimpleDelegator propose deux méthodes: __setobj__ pour définir quel objet est délégué et __getobj__ pour obtenir cet objet.

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

Certains décorateurs comptent sur la magie pour configurer ce comportement, mais vous pouvez rendre plus évidente l'origine de la logique de présentation en initialisant l'objet sur la page.

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

En transmettant une référence à l'objet view dans le décorateur, nous pouvons toujours accéder à tous les assistants de la vue tout en construisant la logique de présentation sans avoir à l'inclure.

Maintenant, le modèle de vue ne concerne que l'insertion de données dans la page, et il est beaucoup plus clair.

Décorer un modèle en utilisant Draper

Draper associe automatiquement les modèles avec leurs décorateurs par convention.

# 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

Étant donné une variable @user contenant un objet ActiveRecord, vous pouvez accéder à votre décorateur en appelant #decorate sur @user ou en spécifiant la classe Draper si vous souhaitez être spécifique.

<% 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow