2011-09-17 5 views
0

Mon point de départ est essentiellement RailsCast de Ryan Bate. J'ai modifié son code pour accommoder les clauses OR ainsi que ET.Passage ou itération à travers BigDecimal

Dans le modèle User, il existe deux attributs nommés hour_price_high et hour_price_low. Les utilisateurs fixeront leur taux horaire, par exemple 45,25 $/h à 55,50 $/h. Les visiteurs du site chercheront des utilisateurs enregistrés dans une fourchette de prix allant de 50,00 $/h à 60,00 $/h. Cette recherche devrait renvoyer tous les utilisateurs qui se chevauchent. Les entrées de migration respectives pour ces attributs sont les suivants:

# CreateUser migration 
... 
t.decimal "hour_price_high", :precision => 6, :scale => 2 
t.decimal "hour_price_low", :precision => 6, :scale => 2 
... 

Ils sont de type BigDecimal et je dois augmenter par ces pour rechercher des utilisateurs:

# Search.rb 
def low_price_or_conditions 
    ["users.hour_price_low IN (?)", price_low..price_high] unless price.blank? 
end 
def high_price_or_conditions 
    ["users.hour_price_high IN (?)", price_low..price_high] unless price.blank? 
end 

Quand je lance ce code, je reçois cette erreur :

TypeError: 
can't iterate from BigDecimal 

Des idées sur la façon d'incrémenter à travers ceux-ci? Je n'ai besoin d'incrémenter que deux décimales. Merci d'avoir regardé!

Répondre

1

Vous ne pouvez pas convertir une plage de BigDecimal à un tableau:

> a = BigDecimal.new('1') 
=> #<BigDecimal:12a082bb0,'0.1E1',9(18)> 
> b = BigDecimal.new('5') 
=> #<BigDecimal:12a076ec8,'0.5E1',9(18)> 
> (a..b).to_a 
TypeError: can't iterate from BigDecimal 

De l'fine manual:

You can only iterate if the start object of the range supports the succ method

Et BigDecimal ne dispose pas d'une méthode succ. Lorsque vous nourrissez ceci:

["users.hour_price_low IN (?)", price_low..price_high] 

à ActiveRecord comme condition, il voit probablement que vous avez donné une plage et des appels to_a sur elle pour obtenir quelque chose qui peut être SQL-ified et c'est là votre erreur provient .

Je pense que vous voulez dire ceci:

[ "users.hour_price_low >= :lo AND users.hour_price_low <= :hi", { :lo => price_low, :hi => price_hi } ] 

Des questions similaires s'appliquent à votre hour_price_high.

Même si price_low et price_high étaient des entiers que vous ne voudriez pas utiliser IN, la gamme pourrait étendre à une liste assez importante et la base de données devrait comparer individuellement.

+0

Vous êtes génial. Votre recommandation> = et <= m'a conduit sur le bon chemin. J'avais besoin d'utiliser une combinaison de ce que vous avez dit et ENTRE. Je devais ajouter ceci aussi: ["users.hour_price_low <=? ET users.hour_price_high> =?", Price_low, price_high] à moins que price.blank? ... ["users.hour_price_low/high ENTRE? ET?", price_low, price_high] sauf si price.blank? Tous les tests passent! Merci encore! – mikeborgh

Questions connexes