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
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
|| 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_attemptdoesn't have frozen progress
- at leas one
enrollmentexist 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?