DEV Community

Augusts Bautra
Augusts Bautra

Posted on

6

Identify and clean up .present? calls on collections

Over the holidays I experimented with an old question I had. "How to find the places in codebase where .present? or .any? is called on a collection?". The answer is important because calling those methods instead of .exists? forces the records in the collection to get loaded from DB into Ruby memory which, depending on the size of the collection, can be a huge performance hit.

After looking into Rails' source, I came up with a monkeypatch that only touches method definitions on ActiveRecord collections. The module that needs prepending is ActiveRecord::Relation.

# in config/application.rb

module CollectionQueryingSafety
  def present?
    raise_warning_about_performance_problems(__method__)
  end

  def blank?
    raise_warning_about_performance_problems(__method__)
  end

  private

    def raise_warning_about_performance_problems(method_name)
      raise(
        ".#{ method_name } called on an AR collection. "\
        "See if .exists? can be used instead."
      )
    end
end

unless Rails.env.production?
  ActiveRecord::Relation.prepend(CollectionQueryingSafety)
end
Enter fullscreen mode Exit fullscreen mode

This snippet will raise errors in non-production environments. Given decent coverage, running your test suite should show most places where suboptimal calls occur.

For example, there could be offensive code like this:

# bad
@my_model.some_has_many_association.present?

# good
@my_model.some_has_many_association.exists?
Enter fullscreen mode Exit fullscreen mode

Now, besides .present? and .blank? there are other array methods - .any?, .none?, and .many? - which in most cases should not be called on collections.
Unfortunately, since these methods accept blocks, I did not feel confident overriding them outright, but in the cases where no block is passed to .any?, .exists? is a much faster and correct alternative.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Cloudinary image

Video API: manage, encode, and optimize for any device, channel or network condition. Deliver branded video experiences in minutes and get deep engagement insights.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay