Шаблон докладчика

Я часто видел шаблон 1, наиболее часто используемый для докладчиков Rails.

1) Зачем ведущему нужен контекст представления?

2) Между шаблоном 1 и шаблоном 2 шаблон 2 кажется проще, так как вам не нужно оборачивать весь код блоком. Почему это не используется чаще? Есть ли недостаток в использовании этого? по сравнению с шаблоном 1?

3) С шаблоном 3, почему люди вообще не используют этот шаблон?

Ведущий

module ApplicationHelper
  def present(model, presenter_class=nil)
    klass = presenter_class || "#{model.class}Presenter".constantize
    presenter = klass.new(model, self)
    yield(presenter) if block_given?
  end
end

class UserPresenter < ApplicationPresenter
  def full_name
    "#{@model.first_name} #{@model.last_name}"
  end

  def birth_year
    return nil unless @model.birthdate
    @model.birthdate.year
  end

  def nickel_per_year
    return nil unless @model.birthdate
    difference = Date.today.year - birth_year
    @view.number_to_currency(difference * 0.05)
  end
end

class ApplicationPresenter < SimpleDelegator
  def initialize(model, view)
    @model, @view = model, view
    super(@model)
  end
end

Узор 1


Использование помощника докладчика в представлении с блоком

Вид

<% @users.each do |u| %>
  <% present(u) do |user| %>
    <tr>
      <td><%= user.full_name %></td>
      <td><%= user.email %></td>
      <td><%= user.birthdate %></td>
      <td><%= user.birth_year %></td>
      <td><%= user.nickel_per_year %></td>
      <td><%= link_to 'Show', user %></td>
      <td><%= link_to 'Edit', edit_user_path(user) %></td>
      <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
<% end %>

Узор 2


Использование презентера в представлении и установка переменной

Вид

<% @users.each do |u| %>
  <% user = UserPresenter.new(user, self) %>
    <tr>
      <td><%= user.full_name %></td>
      <td><%= user.email %></td>
      <td><%= user.birthdate %></td>
      <td><%= user.birth_year %></td>
      <td><%= user.nickel_per_year %></td>
      <td><%= link_to 'Show', user %></td>
      <td><%= link_to 'Edit', edit_user_path(user) %></td>
      <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
<% end %>

Узор 3


Используя презентатор в контроллере, предполагая, что вы можете передать контекст представления при использовании такого решения. https://github.com/endofunky/oprah

UserController

def show
  @user = UserPresenter.new(User.find(params[:id]), view_context)
end

def index
   @users = Users.all.map {|user|  UserPresenter.new(user, view_context) }
end

person user2012677    schedule 21.09.2019    source источник
comment
Шаблон Presenter имеет много недостатков, хотя этот вопрос может быть закрыт как основанный на мнении, возможно, прочитайте этот пост   -  person lacostenycoder    schedule 21.09.2019


Ответы (1)


1) Зачем ведущему нужен контекст представления?

Контекст просмотра позволяет получить доступ к справкам просмотра, таким как link_to и т. д., к которым вы обычно не сможете получить доступ в презентаторе без включения необходимых модулей. Например, вы можете сделать:

def deactivate_button
   view_context.link_to('Deactivate', '...', disabled: deactivated?)
end

2) Между шаблоном 1 и шаблоном 2 шаблон 2 кажется проще, так как вам не нужно оборачивать весь код блоком. Почему это не используется чаще? Есть ли недостаток в использовании этого? по сравнению с шаблоном 1?

Нет никакой практической разницы, кроме как с блоком, вы получаете доступ как к непредставленному пользователю, так и к представленному пользователю. Но нужен ли вам доступ к непредставленному пользователю? Я бы сказал, что нет, и предпочел бы использовать вариант без блокировки.

3) С шаблоном 3, почему люди вообще не используют этот шаблон?

Они это делают, и предпочтительнее установить переменную в контроллере, чем делать это в представлении.

person Kris    schedule 22.09.2019
comment
Какие модули добавляет контекст представления? Если бы я хотел добавить их вручную, не передавая контекст представления? - person user2012677; 23.09.2019
comment
такие модули, как ActionView::Helpers::UrlHelper - person Kris; 23.09.2019