Szukaj…


Uwagi

Wzorzec Dekoratora pozwala dodawać lub modyfikować zachowanie obiektów w sposób sytuacyjny bez wpływu na obiekt podstawowy.

Można to osiągnąć za pomocą zwykłego Ruby za pomocą stdlib lub za pomocą popularnych klejnotów, takich jak Draper .

Dekorowanie modelu za pomocą SimpleDelegator

Większość programistów Railsów zaczyna od modyfikacji informacji o swoim modelu w samym szablonie:

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

W przypadku modeli z dużą ilością danych może to szybko stać się kłopotliwe i prowadzić do logiki kopiowania i wklejania z jednego szablonu do drugiego.

W tym przykładzie użyto SimpleDelegator z stdlib.

Wszystkie żądania do obiektu SimpleDelegator są domyślnie przekazywane do obiektu nadrzędnego. Możesz zastąpić dowolną metodę z logiką prezentacji lub możesz dodać nowe metody specyficzne dla tego widoku.

SimpleDelegator udostępnia dwie metody: __setobj__ aby ustawić, do którego obiektu jest delegowany, i __getobj__ aby uzyskać ten obiekt.

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

Niektórzy dekoratorzy polegają na magii w celu uporządkowania tego zachowania, ale można uczynić bardziej oczywistym, skąd bierze się logika prezentacji, inicjując obiekt na stronie.

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

Przesyłając odwołanie do obiektu widoku do dekoratora, nadal możemy uzyskać dostęp do wszystkich pozostałych pomocników widoku podczas budowania logiki prezentacji bez konieczności jej dołączania.

Teraz szablon widoku dotyczy tylko wstawiania danych na stronę i jest o wiele bardziej przejrzysty.

Dekorowanie modelu za pomocą Drapera

Draper automatycznie dopasowuje modele do dekoratorów zgodnie z konwencją.

# 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

Biorąc pod uwagę zmienną @user zawierającą obiekt ActiveRecord, możesz uzyskać dostęp do dekoratora, wywołując #decorate na @user lub określając klasę Draper, jeśli chcesz być konkretny.

<% 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow