lunes, 25 de enero de 2010

Controllers y Presenters

Cuando nos queremos dar cuenta, tenemos los controladores llenos de código y empiezan a ser pesados y difíciles de mantener. He visto que hay un patrón de diseño que permite mantener toda esta lógica "sobrante" en otra clase, y dejar en los controladores sólo la funcionalidad de recuperar datos de los modelos y decidir el flujo de la navegación. A este patrón lo llaman Presenter.

Consiste en crear una clase donde se haga toda la recogida de datos que se hace en los controladores. Por ejemplo, antes tenia un controlador con esta acción:

def show
  @profile = Profile.active.find(params[:id])
  @friends = @profile.friends.first 12
  @recommended_profiles = @profile.recommended(:limit => 12)
  @graffities = @profile.graffities.all(:limit => 12)
  Comment.preload_wall_associations(@graffities)
 

  store_location
 

  respond_to do |format|
    format.html # show.html.erb
    format.xml { render :xml => @profile }
  end
end


Los hay peores, pero esto se puede sustituir por:

  def show
    @presenter = ProfilePresenter.new(params)
    store_location

    respond_to do |format|
      format.html # index.html.erb
      format.xml { render :xml => @presenter }
    end
  end


Como se ve, en ProfilePresenter dejamos toda la lógica de recogida de datos.

class ProfilePresenter

  def initialize(params)
    @presenter_params = params
  end
 
  def profile
    @profile ||= Profile.active.find(@presenter_params[:id])
  end

  def friends
...

  end


  def recommended
...
  end


  def graffities
...
  end

end



Asi, en las vistas, podemos utilizar @presenter.profile o @presenter.friends, etc. y dejamos los controladores claros y limpios.

Estos presenters pueden dejarse en el directorio app/presenters, por ejemplo. No te olvides de añadir a config/environment.rb la linea:

config.load_paths += %W( #{RAILS_ROOT}/app/presenters)

No hay comentarios:

Publicar un comentario