Never render a layout in response to xhrs
Most of the time I don't want to render a layout when the request comes from AJAX. To this end I've been writing render :layout => !request.xhr?
frequently in my controller actions.
How can I mak开发者_开发技巧e this the default? I.e., I'd like to be able to write
def new
Post.find(params[:id])
end
and have the functionality be
def show
Post.find(params[:id])
render :layout => !request.xhr?
end
(I'm fine manually specifying a layout in the rare cases in which I want to use one.)
How about this?
class UsersController < ApplicationController
layout proc {|controller| controller.request.xhr? ? false : "application" }
end
In order to make it the default to never render a layout for any XHR request, you can do this:
class ApplicationController < ActionController::Base
layout proc { false if request.xhr? }
end
When the request is an XHR request, it renders the requested view without a layout. Otherwise, it uses the default layout behaviour, which looks up the layout by inheritance.
This is different than saying controller.request.xhr? ? false : 'application'
, since that will always render the application
layout for a non-XHR request, which effectively disables the lookup by inheritance.
Also see the ActionView documentation for the nil
argument and layout inheritance.
A normal after_filter won't work because we want to modify rendering.
How about hijacking render?
class ApplicationController < ActionController::Base
private
def render(options = nil, extra_options = {}, &block)
options = {:layout => !request.xhr?}.merge(options) unless options.nil?
super(options, extra_options)
end
end
Set the layout when calling render to override it. A bit ugly but should work.
精彩评论