title: Recommended way to use Rails view helpers in a presentation class
body: <p>I've been researching the 'recommended' way to use Rails view helpers (e.g. <code>link_to</code>, <code>content_tag</code>) in a plain ruby class, such as a presenter. It seems there's very little information on this front and I wanted to get an idea of what the Stack community thought. </p>
  
  <p>So, the options we have are.. (note I'm using Rails 4, and am less concerned about older versions)</p>
  
  <p><strong>Include the required modules manually</strong></p>
  
  <p>This is probably the cleanest way, since only the helpers needed are included. However I have found this method to not work in some cases, as the usual view context provided in plain Rails helpers is configured for the current request. <code>url_for</code> wouldn't know about the current request for example, so the host might not match. </p>
  
  <pre><code>class MyPresenter
      include ActionView::Helpers::UrlHelper
      include ActionView::Helpers::CaptureHelper
  
      def wrapped_link
          content_tag :div, link_to('My link', root_url)
      end
  end
  </code></pre>
  
  <p><strong>Use <code>ActionController::Base.helpers</code></strong></p>
  
  <p>Since Rails 3, <code>ActionController::Base</code> has included a <code>helpers</code> method to access the current view context. I believe the view context provided by this method is configured as it would be in a rails helper, but I might be wrong. There's not really any documentation about this which seems worrying, but it does work quite well in practice. </p>
  
  <pre><code>class MyPresenter
      def wrapped_link
          h.content_tag :div, h.link_to('My link', h.root_url)
      end
  
      protected
  
      def h
          ActionController::Base.helpers
      end
  end
  </code></pre>
  
  <p>I believe this view context can also be mixed in with <code>include</code>, but the rails view helpers have hundreds of methods and it feels dirty to include them all indiscriminately. </p>
  
  <p><strong>Inject the view context when calling the presenter</strong></p>
  
  <p>Finally, we could just pass the view context to the class when it's initialized (or alternatively in a <code>render</code> method)</p>
  
  <pre><code>class MyPresenter
      attr_accessor :context
      alias_method :h, :context
  
      def initialize(context)
          @context = context
      end
  
      def wrapped_link
          h.content_tag :div, h.link_to('My link', h.root_url)
      end
  end
  
  class MyController &lt; ApplicationController
      def show
          # WARNING - `view_context` in a controller creates an object
          @presenter = MyPresenter.new(view_context) 
      end
  end
  </code></pre>
  
  <p>Personally I tend to lean towards the latter two options, but with no definitive answer from the Rails team (that I've been able to find) I felt a bit unsure. Who better to ask than Stack!</p>