1

I am trying to figure out how to set the layout from a custom made responder. I want to use the request.xhr? to set the layout for render to 'ajax'. Does anybody know how to do that? I am using Rails 3 and I have a responder like this:

module AjaxLayoutResponder
  def to_html
    if request.xhr?
      # do something here to change layout...
    end
    super
  end
end

It seem to me like a responder is the best way to accomplish this 'ajax' layout switching.

demersus
  • 1,185
  • 2
  • 10
  • 24

2 Answers2

1

I disagree that a responder is the way to go. Here's an easy solution that I use in most of my projects (however I just set the ajax layout to nil):

In application_controller.rb

layout :set_layout

def set_layout
  request.xhr? 'ajax' : 'application'
end
Josiah Kiehl
  • 3,593
  • 3
  • 26
  • 28
  • That is usually what I do, but this particular project uses layouts that are customized for different controllers. This would always make my layout 'application' instead of the customized one. It seems to me that changing the layout, based on if the request is ajax, actually does fit the description of a responder. Why should the controller care? The responder customizes the response based on the request type. And this would promote dry code reuse. Instead of having to make a custom 'set_layout' for each controller which has a non standard layout. – demersus Nov 22 '10 at 16:09
  • Ah, I see. Do you have your layouts named after your controller? If so, something like this might work: request.xhr? 'ajax' : params[:controller].singularize – Josiah Kiehl Nov 22 '10 at 20:45
  • That seems logical. I will have to try it. Thanks :) – demersus Jan 05 '11 at 22:48
0

you could simply do this:

module AjaxLayoutResponder
  def to_html
    if request.xhr?
      options[:layout] = 'ajax'
    end
    super
  end
end

because what is called at the end of responder execution is:

# from https://github.com/plataformatec/responders/blob/master/lib/action_controller/responder.rb
def default_render
  if @default_response
    @default_response.call(options)
  else
    controller.render(options)
  end
end
Tian Chen
  • 493
  • 4
  • 15