Search code examples
ruby-on-railsrubyrailscastspresenter

Using presenters (Ryan Bates' style) without an associated model


I would like to use presenters (as seen here: http://railscasts.com/episodes/287-presenters-from-scratch?view=asciicast) to clean up my static_pages views, but his method seems to rely on an underlying model, which static_pages does not have. Can I use this method for my static home page?

My user setup (which works well and does have a corresponding model) looks like this:

Presenter:

class UserPresenter < BasePresenter
  presents :user
    def h
      @template
    end

    def admin_text
      if user.admin?
        'This is an admin'
      else
       'This is not an admin'
      end
    end
end

Users/Show:

<% present @user do |user_presenter| %>
    <div class="row">
       <dl>
          <dt>Username:</dt>
          <dt><%= @user.username %></dt>
          <dt>Email:</dt>
          <dt><%= @user.email %></dt>
          <dt><%= user_presenter.admin_text %>
        </dl>
    </div>
<% end %>

I would like to use a similar structure to clean up my _header partial, which is rendered in application.html.erb, a portion of which looks like this:

from _header.html.erb:

<% if current_user && current_user.admin? %>
  <li><a href="#">All Notes</a></li>
<% end %>

How can I use a presenter to move this logic out of the view, and have the view show something like this:

static_presenter.admin_all_notes

to present the necessary view code to home.html.erb?

I'm not sure I asked this in the best way possible, but my goal is to use presenters like Ryan Bates does to clean up my static_pages views, which do not have a corresponding model.

Thanks!

Edit:

I'm specifically confused about how to wrap the static page (e.g. home.html.erb) and what to pass to the block, and following this, how to refer to a method in the presenter class from the static page.


Solution

  • You can use the same approach. You would just need to pick a name for the presenter (e.g. static_presenter) and you wouldn't pass in an instance of a model to the initialization, since you're presenting static or global information. Otherwise, the approach is the same.

    So for your present class, I would think you could have:

    class StaticPagesPresenter
    
      def initialize(template)
        @template = template
        yield self if block_given?
      end
    
      def h
        @template
      end
    
      def admin_notes
        if h.current_user && h.current_user.admin?
           '<li><a href="#">All Notes</a></li>'
        end
      end
    
    end
    

    then within your header partial you could have something like:

    <% StaticPagesPresenter.new(self) do |presenter| %>
    <%   presenter.admin_notes %>
    <% end %>
    

    I'm assuming that there are Rails helpers use can use as an alternative to the HTML currently in admin_notes and I'm not sure if you need the h. to reference current_user.