Lance Pollard
Lance Pollard

Reputation: 79218

How do I specify ":layout => false" in Rails' respond_with?

I have this setup:

class UsersController < InheritedResources::Base
  respond_to :html, :js, :xml, :json

  def index
    @users = User.all
    respond_with(@users)
  end
end

Now I am trying to make it so, if params[:format] =~ /(js|json)/, render :layout => false, :text => @users.to_json. How do I do that with respond_with or respond_to and inherited_resources?

Upvotes: 32

Views: 41082

Answers (7)

Moriarty
Moriarty

Reputation: 4137

class UsersController < InheritedResources::Base
  layout -> (controller) { controller.request.xhr? ? false : 'application' }
end

Upvotes: 2

Jonathan Allard
Jonathan Allard

Reputation: 19249

I just found this out:

Even if it's JSON, Rails is still looking for a layout. As such, the only layout that it finds, in our case, is application.html.

Solution: Make a JSON layout.

So for instance, if you put an empty application.json.erb with a single = yield inside, next to your HTML one, the HTML layout is bettered by the JSON one. You can even use this to surround your JSON with metadata or things like that.

<%# app/views/layouts/application.json.erb %>

<%= yield %>

No other parameters needed, it automagically works!

Tested in Rails 4 only

Upvotes: 5

Jeremy
Jeremy

Reputation: 4930

Or to prevent you having to hardcode responses for each format in each action.

If you have no layouts for any of the actions in this controller it would be nicer to do:

class UsersController < InheritedResources::Base
  respond_to :html, :js, :xml, :json
  layout false

  def index
    @users = User.all
    respond_with(@users)
  end
end

Upvotes: 18

rafudu
rafudu

Reputation: 43

You need to set this on your show action.

def show
  render :layout => !request.xhr?
end

:)

Upvotes: 1

choonkeat
choonkeat

Reputation: 5547

I love @anthony's solution, but didn't work for me... I had to do:

respond_with(@users) do |format|
  format.html { render :layout => !request.xhr? }
end

ps: posting an "answer" instead of a comment because stackoverflow comment formatting and "return key == submit" is infuriating!

Upvotes: 8

Anthony Bishopric
Anthony Bishopric

Reputation: 1296

Assuming you need JSON for an Ajax request

class UsersController < InheritedResources::Base
  respond_to :html, :js, :xml, :json

  def index
    @users = User.all
    respond_with(@users, :layout => !request.xhr? )
  end
end

This seems like the cleanest solution to me.

Upvotes: 28

Yannis
Yannis

Reputation: 5426

Something like:

def index
  @users = User.all
  respond_with @users do |format|
    format.json { render :layout => false, :text => @users.to_json }
  end
end

Upvotes: 45

Related Questions