Ruby on Rails
Motif de décorateur
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>