关于rails中的演示者模式。 这是一个更好的方法吗?
我有我的模特:
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
我以为我认为我错过了主持人的真实概念..但这就是我试图存档的内容,怎么可以称之为?
通常这种事情是通过辅助方法处理的,例如:
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| %> <%= 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| %> <%= profile.link %> <% end %>