开发者

Never render a layout in response to xhrs

开发者 https://www.devze.com 2022-12-23 11:19 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消