abelard2008
abelard2008

Reputation: 2084

why "Completed 406 Not Acceptable" has gone after removing respond_to?

when I used $.ajax() to submit the form's content with the following respond_to block:

respond_to do 
  render :json => { :url => question_path(resource, :recent => :true),
          :uploadPath => question_path(@question, :format => "json"),
          :editPath => edit_question_path(@question),
          :exitPath => question_path(resource)
  }
end

I got a error:

Completed 406 Not Acceptable in 124690.7ms (Views: 0.4ms | ActiveRecord: 16.7ms | Sphinx: 0.0ms)

After I removed respond_to, as the above code is changed into:

  render :json => { :url => question_path(resource, :recent => :true),
          :uploadPath => question_path(@question, :format => "json"),
          :editPath => edit_question_path(@question),
          :exitPath => question_path(resource)
  }

The error has gone, why this happens? what things I miss? Thank you!

Upvotes: 1

Views: 2934

Answers (1)

Frederick Cheung
Frederick Cheung

Reputation: 84132

respond_to is used when you want to produce different responses for the same controller action. For example perhaps you want to render HTML for browsers but JSON for an API client. You list all the responses you can generate (and how they should be generated) and rails picks the one that matches the request:

respond_to do |format|
   format.html { ... }
   format.json { ... }
end

In the example above rails would know how to generate HTML and JSON responses but if a request came in requesting an XML response then rails would produce a 406 error (not acceptable ) because it doesn't know how to produce such a response.

In your code snippet you are calling respond_to so you are telling rails to only use the response formats given by the block but you are not defining any response formats (you're not using the object yielded to the block), therefore rails produces a 406.

When you remove the call to respond_to Rails no longer worries about trying to pick the correct response format and just uses your call to render (and would do so no matter what format the request was asking for).

If you wanted to use respond_to you would do

respond_to do |format|
  format.json { render :json => { ... }}
end

when doing so you do need to ensure that the request is requesting json - if rails though it was requesting HTML then you'd be back to your 406 error. You can use jQuery's dataType option for this or use an extension of .json (ie make your request to /foo/bar.json)

Upvotes: 5

Related Questions