Skip to content

Instantly share code, notes, and snippets.

@nigelr
Forked from addstar34/presenter_design_pattern.rb
Last active December 1, 2017 05:38
Show Gist options
  • Save nigelr/9d20efcc7a2525043a2295edc42b1aae to your computer and use it in GitHub Desktop.
Save nigelr/9d20efcc7a2525043a2295edc42b1aae 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 = PetPresenter.new(Pet.find(params[:id]))
end
end
# app/presenters/pets_presenter.rb
class PetsPresenter
attr_reader :pets, :view_context
def initializer pets, view_context
@pets = pets
@view_context = view_context
end
def self.each
pets.each do |pet|
yield PetPresenter.new(pet, view_context)
end
end
end
class PetPresenter < SimpleDelegator
attr_reader :pet
attr_accessor :view_context
def initialize(pet, view_context)
super(pet)
@view_context = view_context
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