Hypsometry. Modal Synthesis.

On nothingness, degrees of okay, bodies, success, and freaking out.

Sometimes, on Rails, you don’t want a controller method to render anything. For instance, an AJAX request might only need to know that the action succeeded. The status of the response is enough to communicate that, with no rendering required.

So you write render(:nothing => true). Rails renders nothing for you, and, by default, returns a successful status code (200 OK). Simple enough.

But how do you test for that? It’s easy to test for redirections (assert_redirected_to), successful template renderings (assert_template), and specific responses (assert_response). But testing for nothingness?

Rails renders nothingness as “ ”. Not an empty string, that is, but one space.

From a certain theoretical perspective, this is not exactly right. Nothingness in response to a GET should probably return a 204 No Content status code. After all, that is precisely the HTTP definition of “nothing to render”. And, in that case, the protocol dictates that no body be included in the response. Which seems perfect, right? Declare that you’ve got nothing to render and render nothing, communicating success implicitly. Simple and sweet.

(Things get more complicated when dealing with HEAD requests. In that case the client has explicitly asked for the headers and nothing but the headers, with no response body needed.)

However, theory tends to fall apart a bit when in the face of actual browsers. The good folks at Yahoo have looked into this while building the Yahoo User Interface Library, and have figured out that IE6, IE7, Opera, and Safari can’t handle the 204 when it comes via XMLHttpRequest. Errors result, headers are lost, responses are left undefined, and communication failure is wrongly declaimed.

(Just to complicate things further, Safari might actually have fixed this as of 3.0. I’m not clear on that, though. Either way, it’s still a cross-browser issue.)

In other words, 204 No Content will break on some of the most common browsers when used with AJAX.

What to do? Well, pass along the only appropriate status code that the browsers can handle, for starters: 200 OK. Having done that, though, you’ve now set the browsers up to expect some sort of response with their OK. And it seems that if you give Safari a completely empty response body, it freaks out a bit and doesn’t handle the response properly.

Thus the Rails hack of redefining nothingness, in this context, as a little bit of whitespace.

Knowing that, testing for the successful rendering of nothing is easy:

def assert_rendered_nothing
assert_equal(@response.body, " ", "The response was not empty.")
assert_response(:success, "The response was not successful.")
end

Check the body of the response for being “ ” and check the status code to be sure that it indicates success. Okay, and pretty good too.

An aside, though not too far: This makes my third post on nothingness this calendar year. (Cf. nihilism and the hinterlands.) I’m not sure what to say about that.

NB: The Rails definition of success is a simple one. Really, a successful status code is one that’s not in the redirection range (from 300 to 399), the client error range (from 400 to 499), or the server error range (from 500 to 599).

3 Comments, Comment

  1. Perhaps this is tangentially related to the fact that Rails’ String#blank? method considers a String that contains only whitespace to be blank (i.e.- nothing).

    So at least Rails is consistent in its definition of nothingness :-)

  2. Upon further review, it is actually Ruby’s String#blank? that defines whitespace-only strings to be blank.

    So perhaps this is just Rails learning from Ruby :-)

  3. That would be related if we were talking about Rails processing the response from a server. However, this is about Rails generating the response.

Reply to “On nothingness, degrees of okay, bodies, success, and freaking out.”