Question

I was wondering is there any way to define default respond_to for index & show actions in Application Controller with an ability to override in other controllers that need some customization.

I think it's going to be easier with an example.

I'm using InheritedResources, CanCan/Authlogic and WickedPDF gems to generate my pdf and authorize users. I was wondering if I can dry up my code.

Here is what I have

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

This works just fine. But it seems redundant that I need to define format.pdf in every controller that I'm want to generate pdf for. Is there any way to move this to application controller or specify somewhere using inherited resources, and then just override this on a per controller basis? Any ideas?

Thank you

Was it helpful?

Solution

Ok I came up with the following solution for anyone else interested.

I figured I can add a controller that will inherit from InheritedResources, which inherits from ApplicationController, and then have all my other controllers inherit from it ( except for a couple of special cases that will inherit directly from application controller ( like the HomeController, that doesn't have any actions other than index, and is not tied to any particular model) - this way I can define certain defaults - that I keep using in all my controllers such as respond_to, and still enjoy the benefits of InheritedResources gem.

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   

Then in my ProductController I can do this ( notice where my ProductController is inheriting from.

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

Hope this is going to help someone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top