Normally this sort of thing is handled via helper methods, such as:
def profile_link(profile)
profile.link ? content_tag(:a, h(profile.name), :href => profile.link) : 'No profile'
end
It is unfortunate you cannot layer in Presenter-style helper methods that extend a Model at view time. They need to be called in a procedural manner with a parameter, kind of anti-OO.
The Presenter approach is not fully supported in the Rails MVC area because it needs to bind to a view in order to have access to the various helper methods required to properly render content, plus information about the session that may impact the presentation.
A more robust approach might be to do something like this:
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
This would show up in your view as something like:
<% ProfilePresenter.new(self, @profile) do |profile| %>
<div><%= profile.link %>
<% end %>
You can simplify calling this by making a helper method that does something mildly crazy like:
def presenter_for(model)
"#{model.class}Presenter".constantize.new(self, model) do |presenter|
yield(presenter) if (block_given?)
end
end
This means you have a much simpler call:
<% presenter_for(@profile) do |profile| %>
<div><%= profile.link %>
<% end %>