Поиск…


замечания

Шаблон Decorator позволяет добавлять или изменять поведение объектов ситуационным способом, не затрагивая базовый объект.

Это может быть достигнуто, хотя простой Ruby с использованием stdlib, или через популярные драгоценные камни, такие как Draper .

Оформление модели с помощью SimpleDelegator

Большинство разработчиков Rails начинают с изменения своей информации о модели в самом шаблоне:

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

Для моделей с большим количеством данных это может быстро стать громоздким и привести к логике копирования вставки из одного шаблона в другой.

В этом примере используется SimpleDelegator из stdlib.

Все запросы к объекту SimpleDelegator по умолчанию передаются родительскому объекту. Вы можете переопределить любой метод с помощью логики представления или добавить новые методы, специфичные для этого представления.

SimpleDelegator предоставляет два метода: __setobj__ для установки того, для какого объекта делегируется, и __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

Некоторые декораторы полагаются на магию, чтобы связать это поведение, но вы можете сделать его более очевидным, откуда приходит логика представления, инициализируя объект на странице.

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

Передавая ссылку на объект вида в декоратор, мы все равно можем получить доступ ко всем остальным помощникам вида при построении логики представления без необходимости включать его.

Теперь шаблон просмотра касается только вставки данных на страницу, и это гораздо более понятно.

Украшение модели с помощью Draper

Дрейпер автоматически согласовывает модели с их декораторами.

# 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

Учитывая переменную @user содержащую объект ActiveRecord, вы можете получить доступ к своему декоратору, вызвав #decorate в @user , или указав класс Draper, если хотите быть конкретным.

<% 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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow