Skip to content

Instantly share code, notes, and snippets.

@naps62
Last active December 27, 2015 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naps62/7333399 to your computer and use it in GitHub Desktop.
Save naps62/7333399 to your computer and use it in GitHub Desktop.
possible approach to presenter pattern (not tested)
# We want to have something this:
# app/models/user.rb
class User < ActiveRecord::Base
include Presenter::Mixin
end
# or for more customization
class User < ActiveRecord::Base
presented
# or the presenter name can be overriden with
# presented as: :user
end
# app/presenters/user_presenter.rb
class UserPresenter < Presenter::Base
# this is the default, but name can be overriden if it's not the same as this class's name
acts_as_presenter_for :user
# user responds to #teams, but we want to return team_presenters instead of actual teams
presents :teams
# the #original method let's us access the original User model
def some_method
original.teams
end
end
#
# any other file
#
# option 1
@users = present User.all
@user = present(User.find(id))
# option 2
@users = User.all.present # Possibly User.present_all
@user = User.find(id).present
# solution via helper methods
module Presenters
class Base
def self.model_klass
self.name.split('::').last..constantize
end
def self.presents(name)
define_method(name.to_s) do
h.present(target.send(name.to_s))
end
end
end
module Helpers
def present(object, klass = nil)
if object.nil?
nil
elsif object.is_a?(Array) || object.is_a?(ActiveRecord::Relation)
object.map { |element| present_single(element, klass) }
else
present_single(object, klass)
end
end
private
def present_single(object, klass)
if object.class.name =~ /^Presenters::/
object
else
klass ||= "Presenters::#{object.class}".constantize
klass.new(object, self)
end
end
end
#
# example usage
#
# in controllers:
def index
@users = present(User.all)
end
# in presenters:
modules Presenters
class User < Presenters::Base
presents :friends
end
end
# Solution by monkey patch
module HelperMethods
include Rails.application.routes.url_helpers
include Rails.application.helpers # confirm if this works
end
module ActiveRecord
class Base
def present
"Presenters::#{class.name.titleize}".new(self, HelperMethods)
end
end
end
module Enumerable
def present
map(&:present)
end
end
@naps62
Copy link
Author

naps62 commented Nov 6, 2013

@zamith @azevedo-252 @gabrielpoca não sei se receberam ontem um parecido, mas não foi associado á minha conta, fica este que está actualizado

@naps62
Copy link
Author

naps62 commented Nov 6, 2013

@gabrielpoca @zamith @azevedo-252 @ronaldofs
para já olhem só para o primeiro ficherio (01_goal.rb) para tentarmos chegar a acordo sobre o objectivo que se quer

o resto dos ficheiros são rascunhos meus para possiveis implementações

@naps62
Copy link
Author

naps62 commented Nov 6, 2013

a ideia é tentarmos chegar a um acordo sobre o que queremos disto, para eu extrair a coisa para uma gem e não andarmos a refazer presenters de 1001 maneiras diferentes em cada projecto (que é o que está a acontecer de momento)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment