【发布时间】:2020-01-22 05:09:35
【问题描述】:
我经常看到模式 1 最常用于 Rails 演示者。
1) 为什么演示者需要视图上下文?
2) 在模式 1 和 2 之间,模式 2 似乎更容易,因为您不需要用块包装整个代码。为什么不经常使用这个?使用这个有缺点吗? vs 模式 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
用户控制器
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
【问题讨论】:
-
Presenter 模式有很多缺点,尽管这个问题可能会因为基于意见而被关闭,可能是read this post
标签: ruby-on-rails ruby ruby-on-rails-5 presenter