我的模特中有:
def presenter
@presenter ||= ProfilePresenter.new(self)
@presenter
end
ProfilePresenter是一个具有get_link(),get_img_url(size),get_sex(),get_relationship_status()等方法的类,以及与模型无关的其他方法,甚至不是控制器,而是使用多个方法在视图中的时间。
所以现在我通过这样做来使用它们:
Profile.presenter.get_link
# or
Profile.presenter.get_img_url('thumb') # returns the path of the image. is not used to make a db query
我认为我错过了演示者的真实概念..但这就是我试图存档的内容,怎么可以称之为?
答案 0 :(得分:16)
通常这种事情是通过辅助方法处理的,例如:
def profile_link(profile)
profile.link ? content_tag(:a, h(profile.name), :href => profile.link) : 'No profile'
end
遗憾的是,您无法在查看时扩展模型的Presenter样式辅助方法中进行分层。它们需要以一种参数,一种反OO的程序方式被调用。
Rails MVC区域并不完全支持Presenter方法,因为它需要绑定到视图才能访问正确呈现内容所需的各种帮助程序方法,以及可能影响表示的会话信息。
更强大的方法可能是做这样的事情:
class ProfilePresenter
def initialize(view, profile)
@profile = profile
@view = view
yield(self) if (block_given?)
end
def link
@profile.link ? @view.content_tag(:a, @view.h(profile.name), :href => @profile.link) : 'No profile'
end
def method_missing(*args)
@profile.send(*args)
end
end
这会在您的视图中显示为:
<% ProfilePresenter.new(self, @profile) do |profile| %>
<div><%= profile.link %>
<% end %>
你可以通过制作一个有点疯狂的帮助方法来简化调用:
def presenter_for(model)
"#{model.class}Presenter".constantize.new(self, model) do |presenter|
yield(presenter) if (block_given?)
end
end
这意味着你有一个更简单的电话:
<% presenter_for(@profile) do |profile| %>
<div><%= profile.link %>
<% end %>