Guard Clause - simplify your ifs

There is an easy way to make ifs look simpler and easier to understand. The solution is Guard Clauses. Generally, what you do is, you return early for a specific condition.

Guard Clause - simplify your ifs

In our company we have a set of services/jobs that share a common interface. They all share a method called #runnable?.  The point of this method is to check whether the job (or the service) fulfills all the conditions to run the actual logic that is implemented in a #call method.

This is how it looks like in the code

if service.runnable?
  service.call
end

As you imagine the #runnable? method can become pretty hard to read quickly. If you are more experienced you probably saw a situation where at first it is just one simple if. However, the longer this method lives in a codebase, the more complex it becomes. Each time a new feature request comes additional && or || is added...maybe with some negations as well?

This can look something like this.

def runnable?
  course_attempt.present? && 
  !course_attempt.frozen_progress? &&
  enrollments.any?
end

This is probably rather not so complex, but you get the point. In this particular case we have three conditions and the service should run only if all of them are true:

  • course_attempt exists
  • course_attemptdoesn't have frozen progress
  • at leas one enrollment exist for a course

There is an easy way to make it look simpler and easier to understand. The solution is Guard Clauses. Generally, what you do is, you return early for a specific condition.

def runnable?
  return false if course_attempt.blank?
  return false if course_attempt.frozen_progress?

  enrollments.any?
end

Looks much more readable, don't you think?

Photo by Alfredo Gregoris on Unsplash