A Presenter Implementation

Problematic Helpers

There is the concensus that the View has to be free of logic. However there are different approaches, how to achieve that. Ruby on Rails provides Helper for that purpose.
Though Helpers are problematic quite often, because they are available in all Views by default. That means, all Helper share the entire name space.
The difficulty is obvious:

module ArticlesHelper
  def title text
    return if text.blank?
    content_tag(:h3, text)

module ProductsHelper
  def title product
    link_to product.name, product, class: 'title'

The Helper naming (title) is not enough specific. The more Helper methods, the more doubled method names are likely to exist in the name space.
Besides Helpers tend to be cumbersome to test.

Presenter definition

The Presenter pattern is a Decorator pattern specialization. Objects are not only decorated, but also presented in the View context. That said, a Presenter object contains the View context (for the Rails Helpers) apart from the decorated object itself. It acts as a middle-man conveying between View and object.
On the one hand logic can be encapsulated specific to the object and on the other hand it also can be tied to a certain context.
In either case the functionality encapsulation simplifies isolated testing.

A problematic View example

A product model:

$ rails g model Product name:string && rake db:migrate

In the View the name has to be displayed different, depending on whether the product is new or not.
Nested logic in the View:

# app/views/products/show.html.haml
- if @product.in_range_at < 1.month.ago
  %h3.new= @product.name
  %h3= @product.name

likewise the short form:

# app/views/products/show.html.haml
%h3{ class: ('new' if @product.in_range_at < 1.month.ago) }= @product.name

are unacceptable.

A Presenter solution

A simple Presenter class, combining the object with the View for inheritance:

class SimplePresenter
  attr_reader :model

  def initialize model, view
    @model = model
    @view = view


  def h

The ProductPresenter benefits from that and includes the appropriate implementation of the headline component:

class ProductPresenter < SimplePresenter
  NEW_RANGE = 1.month

  def name_tag
    css = 'new' if new?
    h.content_tag(:h3, model.name, class: css)


  def new?
    model.in_range_at < NEW_RANGE.ago

and its usage:

# app/views/products/show.html.haml
= ProductPresenter.new(@product).name_tag

At first glance the Presenter implementation looks extensive. Adopting the Presenter pattern evolves its full effect over more complex components and comprehensive projects.

Reasonable Helpers

Of course Helper make sense for View logic, which is required application wide. This includes not only Rails Helper (e.g. FormTagHelper), but also application specific Helper. Therefore building a Presenter instance should take place in a Helper:

# helpers/application_helper.rb
module ApplicationHelper
  def present(model, presenter_class=nil)
    presenter_class ||= "#{model.class}Presenter".constantize
    presenter_class.new(model, self)

The object presentation in the View is simplified by that:

# app/views/products/show.html.haml
= present(@product).name_tag