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 ajouter "Yale" mais peut ajouter "yale". Comment rendre le cas de validation insensible?
EDIT: Found it - Active Record Validations
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 serveurs/processus serveur (par exemple exécutant Phusion Passenger, plusieurs Mongrels, etc.) ou un serveur multi-thread. C'est parce que vous pourriez obtenir cette séquence d'événements (l'ordre est important):
insert
pour le nouvel enregistrement et réussitinsert
pour le nouvel enregistrement et échouera avec un exception de serveur laid qui revient de l'adaptateur SQL. Si vous n'avez pas de contrainte de base de données, l'insertion réussira et vous avez maintenant deux lignes avec "foo" comme nom.Voir aussi "Concurrence et intégrité" dans le validates_uniqueness_of
Rails documentation.
De Ruby sur Rails 3e édition :
... malgré son nom, validates_uniqueness_of ne garantit pas vraiment que les valeurs des colonnes seront uniques. Tout ce qu'il peut faire 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 que les deux enregistrements passent la validation. Le moyen le plus fiable de faire respecter l'unicité est d'utiliser une contrainte au niveau de la base de données. "
Voir aussi l'expérience de ce programmeur avec validates_uniqueness_of
.
Cela se produit généralement en cas de double soumission accidentelle à partir d'une page Web lors de la création d'un nouveau compte. C'est une question difficile à résoudre car ce que l'utilisateur récupérera 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. La meilleure façon que j'ai trouvée pour empêcher cela est simplement d'utiliser javascript pour empêcher la double soumission.
Dans Rails 3, vous pouvez le faire dans votre modèle:
validates :name, :uniqueness => true
ou sans sensibilité à la casse
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, en utilisant :case_sensitive => false
exécute une requête de base de données très inefficace.