Skip to content

Instantly share code, notes, and snippets.

@addstar34
Last active December 1, 2017 05:25
Show Gist options
  • Save addstar34/ac1bb03991c58ff97821309d8a7daf4d to your computer and use it in GitHub Desktop.
Save addstar34/ac1bb03991c58ff97821309d8a7daf4d to your computer and use it in GitHub Desktop.
Presenter Design Pattern (without double iterating when coming from #index)
# app/controllers/pets_controller.rb
class PetsController < ApplicationController
before_action :set_pet, only: [:show, :edit, :update, :destroy]
def index
# old way
# @pet_presenters = Pet.all.map { |pet| PetPresenter.new(pet, view_context) }
# new way
@pet_presenters = PetsPresenter.prepare(Pet.all, view_context)
end
def show
@pet_presenter = PetsPresenter.new(Pet.find(params[:id]))
end
end
# app/presenters/pets_presenter.rb
class PetsPresenter < SimpleDelegator
attr_reader :pet
attr_accessor :view_context
def initialize(pet, view_context)
super(pet)
@view_context = view_context
end
def self.each
@@pets.each do |pet|
yield new(pet, @@view_context)
end
end
def self.prepare(pets, view_context)
@@pets = pets
@@view_context = view_context
self
end
def display_name
view_context.link_to "#{name} the #{breed}", self
end
end
# app/views/pets/index.html.erb
<% @pet_presenters.each do |pet| %>
<tr>
<td><%= pet.display_name %></td>
<td><%= link_to 'Show', pet %></td>
<td><%= link_to 'Edit', edit_pet_path(pet.id) %></td>
<td><%= link_to 'Destroy', pet, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment