2010-06-06 16 views
44

Sono in procinto di passare il mio ambiente di sviluppo da sqlite3 a postgresql 8.4 e ho un ultimo ostacolo.Come fare l'ordine insensibile alle maiuscole in Rails con postgresql

Nel mio originale ho avuto la seguente riga in un metodo di supporto;

result = Users.find(:all, :order => "name collate NOCASE") 

che ha fornito una ricerca senza distinzione tra maiuscole e minuscole. Non riesco a replicare questo per postgresql. Dovrebbe essere facile - qualche idea?

Grazie.

risposta

77
result = Users.find(:all, :order => "LOWER(name)") 

Prendere un po 'da Brad e Frank.

+0

Nizza, che ha funzionato grazie. Mi ha indirizzato nella giusta direzione per imparare un po 'di più su questo per me stesso. Usando UPPER (nome) funziona anche e in effetti è ciò che è finito nel mio codice - senza una ragione particolare. – brad

+2

Una soluzione più estrema a cui ho fatto ricorso è di avere una colonna in più che tiene traccia della colonna originale. Usando i trigger su insert o update, modifica quella colonna. L'ho usato in passato un paio di volte, dove volevo ordinare i titoli di qualcosa e non volevo che le parole chiave di "a, an, the" contassero. Ho anche spogliato tutti i personaggi speciali. Ciò ha provocato "titolo", "titolo", "titolo", "titolo" ordinamento uno accanto all'altro piuttosto che sparsi in giro. Inoltre, è stato possibile modificare il campo ordinabile in modo da poter rendere "titolo V" prima del "titolo IX". – LanceH

+1

Se è necessario su 'default_scope', utilizzare' order_scope order ('LOWER (name) ASC') '. Mi ha preso un po 'per capire le specifiche. –

5

IN SQL è possibile utilizzare ORDER BY LOWER (nome colonna), non ha idea di come farlo in Ruby. Un indice funzionale (anche su LOWER (nome colonna)) aiuterà a velocizzare le cose.

6

Hai considerato di memorizzare la colonna come tipo citext? In realtà, semplicemente interiorizza la chiamata a lower() come ho capito. In seguito sarebbe automatico per te. Se ci sono volte che hai bisogno di una ricerca case-sensitive, questa potrebbe non essere la migliore idea però.

+0

Interessante. Questo è un nuovo tipo per me. Un po 'di lettura suggerisce che è necessario installare separatamente il modulo citext per abilitare questa funzione in 8.4 (ma sarà incorporato in 9.0). Ciò influenzerebbe la portabilità del mio codice, quindi per ora lo lascerò fuori. Non ho bisogno di fare una ricerca sensibile al caso in questo momento, ma penso che mi piacerebbe mantenere l'opzione aperta in questo momento, quindi lasceremo questo per ora. Molto utile sapere che esiste anche se così grazie! – brad

23

risposta popolare LanecH adattato per Rails 3+ (compresi Rails 4):

users = User.order('LOWER(name)') 

# or create a named scope you can reuse 
class User < ActiveRecord::Base 
    scope :order_by_name, -> { order('LOWER(name)') } 
end 

users = User.order_by_name 
Problemi correlati