2011-08-23 15 views
5

Ho bisogno di trovare i record nell'ordine esatto in cui è passato come parametro di ricerca.Ruby on Rails: trova i record senza Sorting

Ad esempio, ho una stringa:

item_list = "23,12,54,45" 

Con la seguente query, ottengo record nell'ordine asc di 'item_list' - "12,23,45,54".

Inventory.find(item_list.split(",")) 

Come modificare la query precedente in modo che restituisca i record nello stesso ordine di "elenco_articolo".

Grazie.

+0

Qual è il più grande insieme di dati si pensa di aver restituito? – Dex

risposta

4

Prova questa, anche se può funzionare solo in MySQL:

Inventory.where("id IN (#{item_list})").order("find_in_set(id, '#{item_list}')") 

Per i set di dati più piccoli si potrebbe lasciare Rubino ordinare i risultati, ma credo che lasciando il database fare il lavoro per voi è migliore per i set più grandi.

0
item_list.split(",").collect do |item| 
    Inventory.find(item) 
end 
+1

Non dovrebbe essere raccolto invece di ciascuno? –

+0

Questo genererà molte domande. –

+0

@Christopher: Può essere; dipende da cosa stai cercando di fare. In un caso generale, probabilmente hai ragione. Lo cambierò ora. – jnevelson

0
unordered_records = Inventory.where(:id => item_list) 
item_list.collect { |id| unordered_records.detect { |x| x.id == id } } 
1

fare l'ordinamento sul lato client in questo modo:

ids = item_list.split(',') 
items = Inventory.find(ids).sort_by { |i| ids.index(i.id) } 

Questo utilizza una sola query e sort_by calcola solo il blocco una volta per ogni elemento in modo che una parte non dovrebbe essere così costoso. Se hai molti articoli da trattare, puoi facilmente creare un hash che associa l'id al suo indice e usarlo nel blocco sort_by.

L'idea di base è quella di ordinare un array utilizzando la struttura di un altro, per esempio:

>> a = [ 23, 11, 42, 5 ] 
>> b = [5, 23, 11, 42] 
>> b.sort_by { |i| a.index(i) } 
=> [23, 11, 42, 5]