Soluzione dei poveri
Se sei in grado di creare una funzione, puoi usare questa. Ho compilato l'elenco iniziando qui e aggiunto ad esso nel tempo. È abbastanza completo. Potresti anche voler rimuovere alcuni caratteri:
CREATE OR REPLACE FUNCTION lower_unaccent(text)
RETURNS text AS
$func$
SELECT lower(translate($1
, '¹²³áàâãäåāăąÀÁÂÃÄÅĀĂĄÆćčç©ĆČÇĐÐèéêёëēĕėęěÈÊËЁĒĔĖĘĚ€ğĞıìíîïìĩīĭÌÍÎÏЇÌĨĪĬłŁńňñŃŇÑòóôõöōŏőøÒÓÔÕÖŌŎŐØŒř®ŘšşșߊŞȘùúûüũūŭůÙÚÛÜŨŪŬŮýÿÝŸžżźŽŻŹ'
, '123aaaaaaaaaaaaaaaaaaacccccccddeeeeeeeeeeeeeeeeeeeeggiiiiiiiiiiiiiiiiiillnnnnnnooooooooooooooooooorrrsssssssuuuuuuuuuuuuuuuuyyyyzzzzzz'
));
$func$ LANGUAGE sql IMMUTABLE;
La tua query dovrebbe funzionare in questo modo:
find(:all, :conditions => ["lower_unaccent(name) LIKE ?", "%#{search.downcase}%"])
Per le ricerche ancorate a sinistra, puoi utilizzare un indice sulla funzione per molto risultati veloci:
CREATE INDEX tbl_name_lower_unaccent_idx
ON fest (lower_unaccent(name) text_pattern_ops);
Per domande come:
SELECT * FROM tbl WHERE (lower_unaccent(name)) ~~ 'bob%'
Soluzione adeguata
In PostgreSQL 9.1+ , con i privilegi necessari, puoi semplicemente:
CREATE EXTENSION unaccent;
che fornisce una funzione unaccent()
, facendo quello che ti serve (tranne lower()
, usalo in aggiunta se necessario). Leggi il manuale su questa estensione
.
Disponibile anche per PostgreSQL 9.0 ma CREATE EXTENSION
la sintassi è nuova in 9.1.
Maggiori informazioni su unaccent e indici: