ruby-on-railsrubyruby-on-rails-4decoratorpresenter

Remove rails presenter object assignment from view


I am using a namespaced Presenter object to help refactor some view presentation logic for my model attributes.

For one object being sent from the controller I would do

@user = Users::UserPresenter.new(@user)

and that works fine. For a query of users, I created a .present() method that maps and applies the UserPresenter.new to each user, so I do

@users = Users::UserPresenter.present(users)

and that works fine. But what about when I am passing an object that then iterates through a relationship in the view. A simple example would be

  <% appointment.users.each do |user| %>
    <% user = Users::UserPresenter.new(user) %>
    <li> <%= user.age%></li>
  <% end %>

A more complex example would be

  <% appointment.appointment_host.family.users.each do |user| %>
    <% user = Users::UserPresenter.new(user) %>
    <li> <%= user.age%></li>
  <% end %>

user_presenter.rb

module Users
  class UserPresenter < SimpleDelegator 
     # methods
  end
end

I don't like having to set the Presenter object in the view. What is a better way to handle this? Ideally using similar patterns as I have so far.


Solution

  • Perhaps you could create a hierarchy of presenters similar to model associations, and then pass only the root presenters to the view. Something like this:

    class AppointmentPresenter
      def initialize(appointment)
        @appointment = appointment
      end
    
      def users
        Users::UserPresenter.present(@appointment.users)
      end
    
      def host_family_users
        Users::UserPresenter.present(@appointment.appointment_host.family.users)
      end
    
      # or perhaps even indeed create a presenter for each collection:
      def appointment_host
        AppointmentHostPresenter.new(@appointment.appointment_host)
        # this presenter would have the `family` method returning a FamilyPresenter, etc.
      end
    end
    

    I.e. some kind of "decorators" for the model associations, returning presenters instead of model objects.