2011-07-31 2 views
11

Ma base de données de développement est SQLite mais je déploie mon application à Heroku et ils utilisent PostgreSQL.Postgres cas insensible recherche avec Rails

Maintenant, j'ai parfois deux résultats différents qui sortent si j'effectue des recherches car PostgreSQL est sensible à la casse mais SQLite ne l'est pas.

Les rails ne devraient-ils pas standardiser ces choses? Quelles méthodes dois-je utiliser pour résoudre cela?

Here is how to fix it with raw SQL

+1

Je recommanderais de développer sur PostgreSQL si vous déployez sur Heroku. Aucun ORM ne vous protégera du comportement spécifique à la base de données. –

+1

Et j'aime utiliser SQLite localement et Postgre sur l'expédition, donc je ne suis pas lié à une certaine DB. À chacun ses goûts. –

Répondre

41

recherche de cas insensible à Postgres:

  • utilisation ilike au lieu de like (insensible à la casse comme)
  • si vous voulez utiliser =, faire les deux côtés soit SUPERIEUR ou INFERIEUR
+4

Merci! Le problème avec 'like' est que je ne sais pas comment les chaîner avec l'opérateur' OR'. Est-il préférable de l'utiliser avec tous les db supportés par des rails? "" LOWER (titre) COMME LOWER ('% # {search_term}%') "' – antpaw

+1

bien qu'il ne freine pas mon code dans mysql, sqlite et pgsql donc c'est assez bon, merci! – antpaw

+0

utilisez UPPER ou LOWER si vous voulez exécuter le même code sur MYSQL et POSTGRES (bien que ce ne soit évidemment pas la meilleure pratique!) –

4

Un autre DDL façon de gérer c'est le citext type de données, ou TEXT insensible à la casse.

4

Il y a beaucoup de choses relativement courantes qu'ActiveRecord ne gère pas, et LIKE matching est l'une d'entre elles. Voici comment y parvenir en utilisant directement Arel.

Model.where(
    Model.arel_table[:title].matches("%#{search_term}%") 
) 

Vous pouvez installer Arel-Helpers pour en faire un peu plus facile

Model.where(Model[:title].matches("%#{search_term}%")) 

je l'ai déjà recommandé Squeel pour cela, mais le créateur original a cessé de soutenir et il ne semble pas être un temps plein développeur de temps en le maintenant. Et comme il joue avec les API ActiveRecord privées, il a besoin d'une attention constante.

+0

Excellente solution, et Squeel est génial, mais juste un avertissement qu'il s'agit d'un comportement spécifique à Postgres. Si vous cherchez à le faire pour d'autres SGBDR, la sortie peut être sensible à la casse. – kgx

+0

@kgx En fait cet exemple fonctionnera comme prévu dans les deux cas. Comme dit @antpaw ci-dessus, SQLite 'LIKE' est insensible à la casse par défaut. Donc, cela va utiliser 'LIKE' dans SQLite et' ILIKE' dans PostgreSQL. –

Questions connexes