Last Updated: February 25, 2016
·
627
· KieranP

Reduce SQL queries run when generating conditional content

If you need to check for any records before looping over them, don't do the following:

if Post.any?
 content_tag(:div) do
 Post.all.each do |post|
 ...
 end
 end
end

The example above generates two queries. One to count, another to fetch records. It's faster (granted, only fractionally, but it adds up) to do this instead:

posts = Post.all
if posts.any?
 content_tag(:div) do
 posts.each do |post|
 ...
 end
 end
end

That way, you only generate one query.

And if you want it cleaner, extract it to a helper.

def content_tag_if_any(records, tag, &block)
 return if records.none?
 content_tag(tag) do
 records.each do |record|
 yield(record)
 end
 end
end

content_tag_if_any(Post.all, :div) do |post|
 ...
end