Rails: display message when collection is empty

When working on a CRUD based application, starting with the index view, you’ll want to display a collection. But when the collection is empty, you’ll want to let the user know the collection is empty, by showing a message.

Most common scenario I have seen so far is the following construction:

<% if @collection.length > 0 %>
  <%= render @collection %>
<% else %>
  <%= 'No records found' %>
<% end %>

There are some variations upon it. Sometimes you specify the wanted partial and pass the collection through the collection option, etc. In other cases, iterating the collection directly inside the if-statement. While this is  all valid code, it is pretty verbose and well, plain ugly. It clearly states the procedural steps you would need to go through in order to get the wanted result:

  1. check if the collection has elements
  2. if so, render / display your list
  3. if the collection is empty, display a message back to the user.

The whole thing can be rewritten to be more compact and still understandable to other developers:

<%= render(@collection) || 'No records' %>

In the above form, you still have a conditional, but more verbose. The difference here is that you don’t check the length of the collection, but the return value of the render method. Rails will first try and render your collection . If the collection is empty, the render method will return nil. Since the render method is part of the conditional OR ( double pipe ) and the return value is nil (fail) it will result in executing the second part of the conditional and that is displaying the string ‘No records’.

This one-liner can really simplify your views and clean up your front-end code. Most likely, you will render the partial inside a table, so just displaying a string as alternative message is a bad idea. Just replace the plain string with the content_tag helpers to build the necessary row / cell:

<%= render(@collection) || content_tag(:tr, content_tag(:td, 'No records')) %>

Because in the end, you’ll want your front-end code to be as good as the back-end.