Back to Blog

Default response with 204 No Content in Rails 5

on July 3, 2016
This blog is part of our Rails 5 series.

Before Rails 5, when we forget to add template for an action, we get ActionView::MissingTemplate exception.

1
2class UsersController < ApplicationController
3  def index
4    @users = User.all
5  end
6end
7
8Started GET "/users" for ::1 at 2016-06-10 17:10:40 +0530
9Processing by UsersController#index as HTML
10Completed 500 Internal Server Error in 5ms
11
12ActionView::MissingTemplate (Missing template users/index, application/index with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby]}...
13

Similarly, if we don't specify response for a POST request, we will also get ActionView::MissingTemplate exception.

1class UsersController < ApplicationController
2  def create
3    @user = User.new(user_params)
4    @user.save
5  end
6end
1
2Started POST "/users"
3Processing by UsersController#create as HTML
4  Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Max"}, "commit"=>"Create User"}
5   (0.1ms)  begin transaction
6  SQL (2.7ms)  INSERT INTO "users" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "Max"], ["created_at", 2016-06-10 12:29:09 UTC], ["updated_at", 2016-06-10 12:29:09 UTC]]
7   (0.5ms)  commit transaction
8Completed 500 Internal Server Error in 5ms
9
10ActionView::MissingTemplate (Missing template users/create, application/create with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby]}...

In Rails 5, if we don't specify response for an action then Rails returns 204: No content response by default. This change can cause some serious implications during the development phase of the app.

Let's see what happens with the POST request without specifying the response.

1class UsersController < ApplicationController
2  def create
3    @user = User.new(user_params)
4    @user.save
5  end
6end
1Started POST "/users"
2Processing by UsersController#create as HTML
3  Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Max"}, "commit"=>"Create User"}
4   (0.1ms)  begin transaction
5  SQL (2.7ms)  INSERT INTO "users" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "Max"], ["created_at", 2016-06-10 12:29:09 UTC], ["updated_at", 2016-06-10 12:29:09 UTC]]
6   (0.5ms)  commit transaction
7No template found for UsersController#create, rendering head :no_content
8Completed 204 No Content in 41ms (ActiveRecord: 3.3ms)

Rails happily returns with 204: No content response in this case.

This means users get the feel that nothing happened in the browser. Because Rails returned with no content and browser happily accepted it. But in reality, the user record was created in the database.

Let's see what happens with the GET request in Rails 5.

1
2class UsersController < ApplicationController
3  def index
4    @users = User.all
5  end
6end
1
2ActionController::UnknownFormat (UsersController#index is missing a template for this request format and variant.
3
4request.formats: ["text/html"]
5request.variant: []
6
7NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not… nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.):
8

Instead of 204: No Content, we get ActionController::UnknownFormat exception. Rails is being extra smart here and hinting that we are probably missing corresponding template for this controller action. It is smart enough to show us this message as we requested this page via browser via a GET request. But if the same request is made via Ajax or through an API call or a POST request, Rails will return 204: No Content response as seen before.

In general, this change can trip us in the development phase, as we are used to incremental steps like adding a route, then the controller action and then the template or response. Getting 204 response can give a feel of nothing happening where things have actually happened in the background. So don't forget to respond properly from your controller actions.


You might also like

If you liked this blog post, check out similar ones from BigBinary