How do I define default respond_to for index & show action in application controller?
-
12-12-2019 - |
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
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.