2012-02-01 5 views
9

Na przykład rozważmy następujący kod (w modelu):Czy jest jakiś dobry sposób, aby PODNOSIć powielanie zakresu/predykatu logicznego duplikowania?

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 

Pierwszy warunek jest SQL, drugi jest rubin, ale wciąż istnieje oczywista powielanie. Czy jest jakiś dobry sposób, aby to WYSOKIE? Jaka jest najlepsza praktyka w takich przypadkach?

Odpowiedz

2

Istnieją dobre powody, aby mieć zarówno więc mogę uznać to (wszystkie w modelu):

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 
+0

Wygląda na to, że to literówka w zakres definicji ... – Alexis

+0

tak. Poprawiłem to. –

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

Odradzam powyższe, ponieważ ładowałoby to wszystkie popularne rekordy tylko po to, aby sprawdzić, który z nich jest popularny. Może 'self.class.popular.exists? (Id)' może pracować –

+2

@ThongKuah jest jeszcze inny problem ze wszystkimi podobnymi rozwiązaniami - metoda może ewentualnie zwrócić nieprawidłowy wynik, gdy obiekt jest w "brudnych" i 'poglądach' lub' avg_rating 'jest zmieniany, ale nie zapisany – Alexis

+1

Zawsze jest miejsce do nauki w SO. TY dla komentarzy! :) – fuzzyalej

Powiązane problemy