Rails «validates_uniqueness_of» Sensibilité à la casse

Voici le modèle (j’utilise SQLLite3):

class School < ActiveRecord::Base validates_uniqueness_of :name end 

Par exemple, après avoir ajouté “Yale”, je ne peux pas append “Yale” mais je peux append “yale”. Comment puis-je rendre la validation insensible?

EDIT: trouvé – Validations Active Record

validates_uniqueness_of :name, :case_sensitive => false fait l’affaire, mais vous devez garder à l’esprit que validates_uniqueness_of ne garantit pas l’ unicité si vous avez plusieurs processus serveurs / serveurs (par exemple, Phusion Passenger, plusieurs Mongrels, etc.) ou un serveur multithread . C’est parce que vous pourriez avoir cette séquence d’événements (l’ordre est important):

  1. Le processus A reçoit une demande pour créer un nouvel utilisateur avec le nom ‘foo’
  2. Le processus B fait la même chose
  3. Le processus A valide l’unicité de ‘foo’ en demandant à la firebase database si ce nom existe encore et la firebase database indique que le nom n’existe pas encore.
  4. Le processus B fait la même chose et obtient la même réponse
  5. Le processus A soumet l’instruction d’ insert pour le nouvel enregistrement et réussit
  6. Si vous avez une contrainte de firebase database nécessitant l’unicité pour ce champ, le processus B soumettra l’instruction d’ insert pour le nouvel enregistrement et échouera avec une exception de serveur laide renvoyée par l’adaptateur SQL. Si vous ne disposez pas d’une contrainte de firebase database, l’insertion réussira et vous avez maintenant deux lignes avec le nom ‘foo’.

Voir aussi “Concurrence et intégrité” dans la documentation validates_uniqueness_of Rails.

De Ruby on Rails 3rd Edition :

… malgré son nom, validates_uniqueness_of ne garantit pas vraiment que les valeurs des colonnes seront uniques. Tout ce qu’il peut faire, c’est de vérifier qu’aucune colonne n’a la même valeur que celle de l’enregistrement en cours de validation au moment de la validation. Il est possible que deux enregistrements soient créés en même temps, chacun avec la même valeur pour une colonne qui doit être unique et pour que les deux enregistrements réussissent la validation. La méthode la plus fiable pour appliquer l’unicité consiste à appliquer une contrainte au niveau de la firebase database. ”

Voir aussi l’expérience de ce programmeur avec validates_uniqueness_of .

Cela se produit généralement par une double soumission accidentelle depuis une page Web lors de la création d’un nouveau compte. C’est difficile à résoudre car ce que l’utilisateur va récupérer est la deuxième erreur (laide) et cela lui fera penser que son enregistrement a échoué, alors qu’en réalité il a réussi. Le meilleur moyen que j’ai trouvé pour empêcher cela est d’utiliser javascript pour empêcher la double soumission.

Dans les rails 3, vous pouvez le faire dans votre modèle:

 validates :name, :uniqueness => true 

ou sans case_sensitivity

 validates :name, :uniqueness => {:case_sensitive => false} 

Il y a une option où vous pouvez spécifier l’insensibilité à la casse

  validates_uniqueness_of :name, :case_sensitive => false 

Il y a une question similaire mais la réponse est plus intéressante: https://stackoverflow.com/a/6422771

Fondamentalement, l’utilisation de :case_sensitive => false effectue une requête de firebase database très inefficace.