1

I'm trying to use bare bones rails controllers and have a more fine-grained control at the same time. If I'm on :new action, I respond_with my new @instance and I get a status code 200 and render the :new template. On show, same thing, different template. So far, so good. But, on the create, I'm having something unexpected. If the new record was successfully and I call respond_with on it, I am redirected to show (status code 302), which is right. But if the new record couldn't be created because the record wasn't valid, the default respond_with is responding by issuing status code 200 and rendering the new template. The template is right, the status code is not. Shouldn't the response code be in such a case 422 (unprocessable entity)?

ChuckE
  • 5,610
  • 4
  • 31
  • 59
  • I've never seen Rails return a 422. It seems like it'd be appropriate in that situation, but I don't think Rails returns it by default. Maybe it will in a JSON response? You could always force it by including a `status: :unprocessable_entity` in your `render`. – Jim Stewart Apr 01 '13 at 19:02
  • how do I set the status in a respond_with? That's my question. Also, what does render has to do, from a semantic point of view, with the response packet? It seems render bundles the packet together and delivers it to the rack handler. Why can't I set response stuff outside of the render scope? I find that limiting. – ChuckE Apr 01 '13 at 22:20

1 Answers1

1

Rails returns a 200 response because it successfully rendered the 'new' template. For non-AJAX requests, this usually works fine, as you'll also display the validation errors to the user in that case so they know what happened.

The only reason you should need the 422 response is if the information was submitted via AJAX, and your client-side javascript is depending on the response code to know what to do. Like Jim said, you can always force the response code with the :status option to render if you need that. In the default 'simple' case though without AJAX involved, you probably don't need it.

Update: A jQuery client might depend on the response code by including an 'error' callback to the .ajax function, or via .ajaxError.

sockmonk
  • 4,195
  • 24
  • 40
  • I beg to differ. status code doesn't have to do with whether the response was rendered or not. An HTTP response, regardless of status code, has a body which is encoded in some format. An HTTP 404 error response with a valid HTML body will be rendered by any browser. The status code is actually important for browsers. On the other hand, an AJAX response behaves differently. Have you ever tried issuing an AJAX response with javascript body from Rails with a 4xx status code, using, let's say, jQuery? I can tell you that it won't work. jQuery won't eval body from non-200 responses. – ChuckE Apr 01 '13 at 22:25
  • And there is no such thing as a successful "new" template rendering. Rails builds the response, but doesn't render it. The browser renders it. Rails builds many response packets, including 404 and 500 standard responses, which always get rendered by browsers, otherwise you wouldn't see that beautiful backtrace on dev mode. – ChuckE Apr 01 '13 at 22:27
  • Rails has a method called `render` which is invoked either explicitly or implicitly when a controller action is processed. It's normal to refer to this process as "rendering" in Rails nomenclature. The browser will "render the rendered response" in this sense. Perhaps an overloaded term, but not incorrect in any way. – Jim Stewart Apr 01 '13 at 22:40