Alexis
Alexis

Reputation: 4499

Is there any good way to DRY up scope / predicate logic duplication?

For example, consider the following code (in a model):

scope :popular, where("views >= 250 OR (views >= 10 AND avg_rating >= 4.75)")

def popular?
  views >= 250 or views >= 10 && avg_rating >= 4.75
end

First condition is SQL, second one is ruby, but still, there's an obvious duplication. Is there any good way to DRY it up? What is best practice for such cases?

Upvotes: 10

Views: 702

Answers (2)

Michael Durrant
Michael Durrant

Reputation: 96614

There are good reasons to have both so I might consider this (all in model):

VIEWS_QUALIFIER = 250
RATING_VIEWS_QUALIFIER = 10
RATING_QUALIFIER = 4.75

scope :popular, where("views >= ? OR (views >= ? AND avg_rating >= ? ",
                VIEWS_QUALIFIER, RATING_VIEWS_QUALIFIER, RATING_QUALIFIER)

def popular?
  views >= VIEWS_QUALIFIER or 
  (views >= RATING_VIEWS_QUALIFIER && avg_rating >= RATING_QUALIFIER)
end

Upvotes: 2

fuzzyalej
fuzzyalej

Reputation: 5973

def popular?
  !!self.class.popular.includes? self
end

Upvotes: -1

Related Questions