Last active
December 27, 2015 13:29
-
-
Save naps62/7333399 to your computer and use it in GitHub Desktop.
possible approach to presenter pattern (not tested)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
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
@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