Default response with 204 No Content in Rails 5

Abhishek Jain

Abhishek Jain

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.


class UsersController < ApplicationController
  def index
    @users = User.all
  end
end

Started GET "/users" for ::1 at 2016-06-10 17:10:40 +0530
Processing by UsersController#index as HTML
Completed 500 Internal Server Error in 5ms

ActionView::MissingTemplate (Missing template users/index, application/index with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby]}...

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

class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    @user.save
  end
end

Started POST "/users"
Processing by UsersController#create as HTML
  Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Max"}, "commit"=>"Create User"}
   (0.1ms)  begin transaction
  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]]
   (0.5ms)  commit transaction
Completed 500 Internal Server Error in 5ms

ActionView::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.

class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    @user.save
  end
end
Started POST "/users"
Processing by UsersController#create as HTML
  Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Max"}, "commit"=>"Create User"}
   (0.1ms)  begin transaction
  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]]
   (0.5ms)  commit transaction
No template found for UsersController#create, rendering head :no_content
Completed 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.


class UsersController < ApplicationController
  def index
    @users = User.all
  end
end

ActionController::UnknownFormat (UsersController#index is missing a template for this request format and variant.

request.formats: ["text/html"]
request.variant: []

NOTE! 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.):

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.

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.