Paul Richter Paul Richter - 1 month ago 13
Ruby Question

Adding custom HTTP status code symbols

Background: Generally, in situations where we want to manually specify the HTTP status code to be returned in the response, Rails gives us a nice set of pre-defined human-readable Ruby symbols to use, rather than explicitly using the numeric values for those codes.

We can do something like the following, for example:

render text: "hurray!", status: :ok


Which is of course ultimately the same as this:

render text: "hurray!", status: 200


In my situation, I would like to render a custom HTTP status code (I've arbitrarily chosen the number 242). Obviously, this code is not standard, and doesn't have a symbolic representation within Rails, so I have to use the actual numeric value.

Current Solution: In order to keep it relatively human-readable in code, I have placed a constant in one of my constant files, like so:

initializers/constants.rb

NEEDS_UPDATE_CODE = 242


And in my controller, I render like so:

render text: "whatever I want to render", status: NEEDS_UPDATE_CODE


Question: This obviously works just fine, but it has me wondering, is there a way to add a new symbolic representation for a custom HTTP status code to Rails?

Answer

I found the answer whilst writing the question. Since I cannot find any duplicates presently on SO, I shall post this answer in case anyone else ever has the same question.

The initial set of symbol representation-HTTP status code mappings is located in the Rack::Utils module, in an accessible hash called SYMBOL_TO_STATUS_CODE. Additionally, the human-readable status code mappings is located in HTTP_STATUS_CODES.

In order to use the symbolic representation in my code, I simply added this in my initializer:

Rack::Utils::SYMBOL_TO_STATUS_CODE[:application_needs_update] = 242

Which allows me to use that symbol like so:

render text: "whatever I want to render", status: :application_needs_update

Unfortunately, the rails log will only show the status code, for example:

Completed 242 in 363ms (Views: 8.6ms | ActiveRecord: 12.0ms)

Which is not terribly helpful for someone who is not familiar with my custom code. In order to rectify that, I can add this in the same file:

Rack::Utils::HTTP_STATUS_CODES[242] = "Application Needs Update"

As a result, when a request is completed using this code, my log will show this:

Completed 242 Application Needs Update in 363ms (Views: 8.6ms | ActiveRecord: 12.0ms)