我想为Event
制作一个索引操作的演示者。
这是它的样子。将会有更多的方法和内容添加到演示者和视图中,但是现在我只想让它工作:
class EventPresenter
def initialize(events, template)
@events = events
@template = template
end
def h
@template
end
def event_title
h.link_to event.name, event_path(event)
end
end
index.html.erb:
<% present @events do |event_presenter| %> <tr>
<td><%= event_presenter.event_title %></td>
<% end %>
应用程序助手:
module ApplicationHelper
def present(object, klass = nil)
klass ||= "#{object.class}Presenter".constantize
presenter = klass.new(object, self)
yield presenter if block_given?
presenter
end
end
events_controller:
def index
@events = Event.all.map{ |event| EventPresenter.new(event) }
# render json: @events
end
现在的方式,我得到了演示者初始化方法的wrong number of arguments (1 for 2)
错误。我试图通过删除@events
或@template
来查看两个对象中的哪一个没有传递到初始化程序中,例如:
def initialize(template)
@template = template
end
但是,在这两种情况下,app都会在{_ 1}}的{{1}}行与klass ||=
一起中断,而它应该在寻找uninitialized constant ArrayPresenter
常量。
完整追踪:
EventPresenter
答案 0 :(得分:0)
您似乎通过在视图层中调用event
方法将present
对象与演示者包装在一起,因此在控制器中执行相同的操作对我来说是多余的。而且,实际上这是一行导致wrong number of arguments
,因为你只用一个参数包装它。我们将其删除:
# events_controller
def index
@events = Event.all
# we removed redundant EventPresenter.new(event) here
end
下一步是您的视图模板。只要@events
包含一系列元素(您可以检查object
辅助方法中的present
参数类),就会"#{object.class}Presenter".constantize
以{{1}结尾因为没有"ArrayPresenter".constantize
这样的类,这会导致错误。你可以在这里解决这个问题的方法是首先迭代一个数组:
ArrayPresenter
另一种选择可能是在helper方法中迭代一个集合。您可能对某些现有解决方案感兴趣,例如Draper gem,以了解它们如何解决包装问题的对象。