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.
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.