relation .present? and .blank? should not query SELECT COUNT(DISTINCT id) #5461

merged 1 commit into from Mar 16, 2012

2 participants


It's a good practice to write "if @post.present?" instead of "if @posts", because it will be more readable.
however, if we are using lists, and say "if @posts.blank?" it will trigger a SELECT COUNT,
not only that, if you use JOINS, it will trigger "SELECT COUNT(DISTINCT 'posts'.id)"
that meaningless query will only affect the performance of the overall request.

Programmers know if they invoke .count or .exists? they will trigger these smaller queries "on purpose"
but methods blank? and present? invoke .empty? internally, which gets overwritten by relations.

I have seen this common miss-usage of a good practice in 02 legacy apps that I've worked already,
and I believe, it would be a good improvement in Rails if those methods (that are commonly used for checks in the view layer to display a custom message for empty), would trigger the SQL query directly, thus not invoking a COUNT DISTINCT just for checking.


In a single request, where I found 05 examples of @sales.blank? in the view, I was able to reduce the load in ~45 seconds in a complex query with joins, that were invoking SELECT COUNT by a programmer's erroneous attempt to do well-written code.

@josevalim josevalim merged commit fa7a3aa into rails:master Mar 16, 2012
Ruby on Rails member

Could you also add a test case please? Maybe you could use a method called assert_queries to ensure just one query is done after a @posts.blank?; @posts.to_a call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment