2009-07-21 8 views
1

J'ai besoin de sélectionner des fourchettes de prix dynamiques soumises à partir d'un formulaire de recherche. Comment dois-je aborder cela avec des étendues? Je cherche quelque chose comme çaRails, travaillant avec named_scope

Painting.price_range ([ '1..500', '2000..5000'])

SELECT * FROM paintings WHERE price BETWEEN 1..500 **OR** BETWEEN 2000..5000 etc. 

Meilleures salutations. Asbjørn Morell.

Répondre

2

Vous aurez besoin d'utiliser un lambda sur le named_scope. Ce qui suit devrait fonctionner:

named_scope :price_range, lambda { |ranges| 
    { 
     :conditions => ["(" + 
     ranges.collect {"price between ? and ?"}.join(" or ") + 
         ")"] + 
     ranges.collect {|r| [r.min, r.max]}.flatten 
    } 
    } 

Le premier ranges.collect crée autant de contrôles « between ? and ? » que vous avez des plages, puis la deuxième ranges.collect aplatit les gammes et les valeurs que AJOUTE à assainie dans les conditions. J'ai coincé des parenthèses autour des orcs juste pour être du bon côté.

+0

Très bien! Votre exemple fonctionne très bien: Painting.price_range ([['1', '200'], ['1000', '2000']]) Peinture Charge (0.4ms) SELECT * FROM 'paintings' O WH ((prix entre '1' et '200' ou prix entre '1000' et '2000')) Merci beaucoup de me donner la solution sur une plaque d'or comme ça :) – atmorell

+0

J'ai quelques problèmes à essayer d'appeler la portée de un formulaire: Paramètres: {"commit "=>" Enregistrer les modifications "," search "=> {" price_range "=>" [[1, 1000]] "}} La requête générée à partir de ceci est: SELECT * FROM' pai ntings' WHERE ((prix entre '[[1, 1000]]' et '[[1, 1000]]')) Je pense que le problème est que la valeur de la forme n'est pas reconnue comme un tableau:/params [search] [price_range] .class retourne la chaîne au lieu du tableau. Des suggestions? – atmorell

+0

Ouais, la solution dans la réponse est pour un tableau de plages plutôt qu'un tableau de paires. Si vous changez r.min et r.max pour r.first et r.last cela devrait fonctionner aussi pour les paires. – Shadwell

4
named_scope :price_range, :conditions => ["(price BETWEEN 1 AND 500) OR (price BETWEEN 2000 AND 5000)"] 

OU

named_scope :price_range, :conditions => ["(price ?) OR (price ?)", (1..500).to_s(:db), (2000..5000).to_s(:db)] 

Dynamic

named_scope :price_between, lambda { |from, to| { :conditions => ['price > ? AND price <= ?', from, to] } } 

named_scope :price_between, lambda { |from, to| { :conditions => ['price BETWEEN ? AND ?', from, to] } } 

->

MyModel.price_between(1,100) 
Questions connexes