2010-05-12 7 views
5

que tengo en mi modelo:Sobre el patrón del presentador en rieles. es una mejor manera de hacerlo?

def presenter 
    @presenter ||= ProfilePresenter.new(self) 
    @presenter 
end 

El ProfilePresenter es una clase que tiene métodos como, get_link(), get_img_url (tamaño), get_sex(), get_relationship_status() y otros métodos que no tienen que ver con el modelo, ni siquiera con el controlador, pero se usa varias veces en la vista.

Así que ahora las uso al hacer esto:

Profile.presenter.get_link 
# or 
Profile.presenter.get_img_url('thumb') # returns the path of the image. is not used to make a db query 

Sincerelly Creo que perdí el concepto real de presentadores .. pero esto es lo que estoy tratando de archivar, ¿cómo se puede llamar esto?

Respuesta

16

Normalmente este tipo de cosas se maneja a través de métodos de ayuda, tales como:

def profile_link(profile) 
    profile.link ? content_tag(:a, h(profile.name), :href => profile.link) : 'No profile' 
end 

Es desafortunado que no puede capa de métodos auxiliares de estilo Presentador que se extienden en modelo a la hora del punto de vista. Deben llamarse de manera procedimental con un parámetro, tipo de anti-OO. El enfoque del presentador no es totalmente compatible en el área Rails MVC porque necesita vincularse a una vista para tener acceso a los diversos métodos auxiliares necesarios para representar el contenido correctamente, más información sobre la sesión que puede afectar la presentación .

Un enfoque más sólido podría ser la de hacer algo como esto:

class ProfilePresenter 
    def initialize(view, profile) 
    @profile = profile 
    @view = view 

    yield(self) if (block_given?) 
    end 

    def link 
    @profile.link ? @view.content_tag(:a, @view.h(profile.name), :href => @profile.link) : 'No profile' 
    end 

    def method_missing(*args) 
    @profile.send(*args) 
    end 
end 

Esto mostrará en la vista como algo parecido a:

<% ProfilePresenter.new(self, @profile) do |profile| %> 
<div><%= profile.link %> 
<% end %> 

Se puede simplificar llamar a esto haciendo un ayudante método que hace algo levemente loco como:

def presenter_for(model) 
    "#{model.class}Presenter".constantize.new(self, model) do |presenter| 
    yield(presenter) if (block_given?) 
    end 
end 

Esto significa que tiene un mucho más simple llamada:

<% presenter_for(@profile) do |profile| %> 
<div><%= profile.link %> 
<% end %> 
+0

Este es un enfoque muy agradable. Limpiar. ¿Estás usando algo como esto ahora? – nathanvda

+0

No es más fácil de usar: "@ profile.presenter.get_url" y está listo para funcionar? o podría estar más comprimido como: "@ profile.pr.get_url". Eso porque no uso mucho solo en bucles pero otras cosas así que el uso sería: "presenter_for (@profile) .get_url" –

+0

@nathanvda He utilizado enfoques como este con envoltorios antes, aunque incluso ellos no siguieron el Patrón del presentador tan de cerca. Esta es una técnica para unir los mundos Model y View. – tadman

Cuestiones relacionadas