2011-08-23 10 views
5

Muszę znaleźć rekordy w dokładnej kolejności, ponieważ są przekazywane jako parametr wyszukiwania.Ruby on Rails: Znajdź rekordy bez sortowania

Na przykład, mam ciąg znaków:

item_list = "23,12,54,45" 

z następującym zapytaniem, otrzymuję rekordy w kolejności ASC 'item_list' - "12,23,45,54".

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

Jak zmodyfikować powyżej zapytania takie, że zwraca rekordy w tej samej kolejności „item_list”.

Dzięki.

+0

Jaki jest największy zbiór danych planujemy po powrocie? – Dex

Odpowiedz

4

Spróbuj tego, choć może pracować tylko w MySQL:

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

Dla mniejszych zbiorów danych mógłby pozwolić Ruby sortowania wyników, ale myślę, pozwalając bazę do pracy dla Ciebie jest najlepsze dla większych zestawów.

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

Czy nie powinno się tego zbierać zamiast każdego? –

+0

Spowoduje to uruchomienie wielu zapytań. –

+0

@ Christopher: Może być; zależy od tego, co próbujesz zrobić. W ogólnym przypadku prawdopodobnie masz rację. Zmienię to teraz. – jnevelson

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

Wykonaj sortowania po stronie klienta jak ten:

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

ten wykorzystuje tylko jedną kwerendę i sort_by oblicza tylko blok raz dla każdego elementu tak, że część nie powinno być kosztowny. Jeśli masz dużo przedmiotów, z którymi możesz sobie poradzić, możesz łatwo zbudować skrót, który odwzoruje identyfikator na jego indeks i użyje go w bloku sort_by.

Podstawowym założeniem jest, aby posortować jedną tablicę używając struktury innego, na przykład:

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