Ruby on Rails
Decorateur patroon
Zoeken…
Opmerkingen
Met het Decorator-patroon kunt u gedrag van objecten op een situationele manier toevoegen of wijzigen zonder het basisobject te beïnvloeden.
Dit kan worden bereikt via gewone Ruby met behulp van de stdlib, of via populaire edelstenen zoals Draper .
Een model versieren met SimpleDelegator
De meeste Rails-ontwikkelaars beginnen met het aanpassen van hun modelinformatie binnen de sjabloon zelf:
<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>
Voor modellen met veel gegevens kan dit snel omslachtig worden en leiden tot copy-paste-logica van de ene sjabloon naar de andere.
In dit voorbeeld wordt SimpleDelegator
uit de stdlib gebruikt.
Alle aanvragen voor een SimpleDelegator
object worden standaard doorgegeven aan het bovenliggende object. U kunt elke methode overschrijven met presentatielogica of u kunt nieuwe methoden toevoegen die specifiek zijn voor deze weergave.
SimpleDelegator
biedt twee methoden: __setobj__
om in te stellen naar welk object wordt gedelegeerd en __getobj__
om dat object te krijgen.
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
Sommige decorateurs vertrouwen op magie om dit gedrag af te ronden, maar je kunt duidelijker maken waar de presentatielogica vandaan komt door het object op de pagina te initialiseren.
<% user = UserDecorator.new(@user, self) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>
Door een verwijzing naar het weergaveobject door te geven aan de decorateur, hebben we nog steeds toegang tot alle andere weergavehulpmiddelen terwijl we de presentatielogica bouwen zonder deze op te nemen.
Nu houdt de weergavesjabloon zich alleen bezig met het invoegen van gegevens op de pagina, en het is veel duidelijker.
Een model versieren met Draper
Draper koppelt modellen volgens afspraak automatisch aan hun decorateurs.
# 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
Gegeven een @user
variabele die een ActiveRecord-object bevat, kunt u toegang krijgen tot uw decorateur door #decorate
aan te roepen op de @user
of door de Draper-klasse op te geven als u specifiek wilt zijn.
<% user = @user.decorate %><!-- OR -->
<% user = UserDecorator.decorate(@user) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>