Ruby on Rails
Dekorateur-Muster
Suche…
Bemerkungen
Mit dem Decorator-Muster können Sie das Verhalten von Objekten situationsabhängig hinzufügen oder ändern, ohne das Basisobjekt zu beeinflussen.
Dies kann durch einfaches Ruby mit der stdlib oder durch beliebte Edelsteine wie Draper erreicht werden .
Dekorieren eines Modells mit SimpleDelegator
Die meisten Rails-Entwickler beginnen mit der Modifizierung ihrer Modellinformationen in der Vorlage selbst:
<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>
Bei Modellen mit vielen Daten kann dies schnell mühsam werden und zu einer Kopierlogik von einer Vorlage in eine andere führen.
In diesem Beispiel wird SimpleDelegator
aus der stdlib verwendet.
Alle Anforderungen an ein SimpleDelegator
Objekt werden standardmäßig an das übergeordnete Objekt übergeben. Sie können jede Methode mit der Präsentationslogik überschreiben oder neue Methoden hinzufügen, die für diese Ansicht spezifisch sind.
SimpleDelegator
bietet zwei Methoden: __setobj__
, um __setobj__
an welches Objekt delegiert wird, und __getobj__
, um das Objekt __getobj__
.
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
Einige Dekorateure verlassen sich auf Magie, um dieses Verhalten zu verknüpfen. Sie können jedoch deutlich machen, woher die Präsentationslogik kommt, indem Sie das Objekt auf der Seite initialisieren.
<% user = UserDecorator.new(@user, self) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>
Durch die Übergabe eines Verweises auf das Ansichtsobjekt in den Dekorateur können wir trotzdem auf alle übrigen Ansichtshilfen zugreifen, während Sie die Präsentationslogik erstellen, ohne sie hinzufügen zu müssen.
Die Ansichtsvorlage befasst sich jetzt nur noch mit dem Einfügen von Daten in die Seite und ist deutlich übersichtlicher.
Dekorieren eines Modells mit Draper
Draper passt Modelle automatisch an ihre Dekorateure an.
# 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
Bei einer @user
Variablen, die ein ActiveRecord-Objekt enthält, können Sie auf Ihren Dekorateur zugreifen, indem Sie #decorate
für den @user
oder die Draper-Klasse @user
, wenn Sie spezifisch sein möchten.
<% user = @user.decorate %><!-- OR -->
<% user = UserDecorator.decorate(@user) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>