Me preguntaba si hay alguna forma de definir respon_to predeterminado para indexar y mostrar acciones en Application Controller con la capacidad de anular en otros controladores que necesitan alguna personalización.

Creo que será más fácil con un ejemplo.

Estoy usando las gemas InheritedResources, CanCan / Authlogic y WickedPDF para generar mi pdf y autorizar a los usuarios. Me preguntaba si puedo secar mi código.

Esto es lo que tengo

class ProductsController < InheritedResources::Base
  load_and_authorize_resource
  respond_to :html, :xml, :json, :pdf

  def index
    @products = Product.page(params[:page])
    index! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  

  def show
    show! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end
end



class CustomersController < InheritedResources::Base
  def index
    index! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  

  def show
    show! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end
end

Esto funciona bien. Pero parece redundante que necesite definir format.pdf en cada controlador para el que quiero generar pdf. ¿Hay alguna forma de mover esto al controlador de la aplicación o especificar en algún lugar usando recursos heredados, y luego simplemente anular esto por controlador? ¿Algunas ideas?

Gracias

2
konung 12 mar. 2012 a las 21:12

1 respuesta

La mejor respuesta

Ok, se me ocurrió la siguiente solución para cualquier otra persona interesada.

Pensé que podía agregar un controlador que heredará de InheritedResources, que hereda de ApplicationController, y luego hacer que todos mis otros controladores hereden de él (excepto por un par de casos especiales que heredarán directamente del controlador de la aplicación (como el HomeController, que no no tiene ninguna acción que no sea index, y no está vinculado a ningún modelo en particular), de esta manera puedo definir ciertos valores predeterminados, que sigo usando en todos mis controladores, como respond_to, y aún disfruto de los beneficios de la gema InheritedResources.

class DefaultInheritedResourcesController < InheritedResources::Base
  # For CanCan authorization - pretty much makes it application wide, without the need
  # to define it in each controller. Can still override it in ability.rb by making    
  # a resource readable to all users with a session.
  #  if user
  #    can :read, [Product]
  #  end 
  # Also for controllers that need special treatment, you can just inherit from ApplicationController
  # and override with skip_authorization_check - but for my app it's rare (only HomeController),
  # most of controllers deal with some kind of resource - so this is a useful convention for 99% of use cases. 

  load_and_authorize_resource 
  respond_to :html, :json, :xml, :pdf

  # format pdf needs to be redefined on those actions where index! or show! are called.
  def index
    super do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  

  def show
    super do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  
end   

Luego, en mi ProductController puedo hacer esto (observe de dónde está heredando mi ProductController.

class ProductsController < DefaultInheritedResourcesController
  def index
    @products = Product.page(params[:page])
    super
  end 
end

Espero que esto ayude a alguien.

2
konung 13 mar. 2012 a las 18:42