Posted 6 months ago. Visible to the public. Repeats.

XHR is not JSON

When a Rails controller action should handle both HTML and JSON responses, do not use request.xhr? to decide that. Use respond_to.

I've too often seen code like this:

Copy
def show # ... if request.xhr? render json: @user.as_json else # renders default HTML view end end

This is just plain wrong. Web browsers often fetch JSON via XHR, but they (should) also send the correct Accept HTTP header to tell the server the data they expect to receive.

If you say request.xhr? as a means for "wants JSON" you are locking out any client applications that correctly send Accept: application/json as a "regular" (non-XHR) request. And you are messing up responses for XHRs that want to load something else (like HTML views in Unpoly).

Your actions should choose the response format via the respond_to method:

Copy
def show # ... respond_to do |format| format.html # renders default HTML view format.json { render json: @user.as_json } end end

If your JSON is a bit more complex than the example above, you should put it into its own view (e.g. show.json.jbuilder). You can then refer to both views in your controller:

Copy
def show # ... respond_to :html, :json end
Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Avatar
Arne Hartherz
Last edit:
6 months ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more