Existe-t-il un moyen de valider qu'un enregistrement réel est unique et pas seulement une colonne? Par exemple, un modèle / une table d'amitié ne devrait pas pouvoir avoir plusieurs enregistrements identiques comme:
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
Is there a rails-way way
. Et vous lui proposez de manière non-rails, mais standard.The Active Record way claims that intelligence belongs in your models, not in the database.
validates :field_name, unique: true
est sujette aux conditions de course, donc même si contre rail-way, une contrainte réelle est préférée. @HarryJoy Je vais voter pour une réponse décrivant la manière de contrainte.Réponses:
Vous pouvez définir un
validates_uniqueness_of
appel comme suit.la source
validates_uniqueness_of [:user_id, :friend_id]
. Peut-être que cela doit être corrigé?Vous pouvez utiliser
validates
pour valideruniqueness
sur une colonne:La syntaxe de la validation sur plusieurs colonnes est similaire, mais vous devez plutôt fournir un tableau de champs:
Cependant , les approches de validation présentées ci-dessus ont une condition de concurrence et ne peuvent pas garantir la cohérence. Prenons l'exemple suivant:
les enregistrements de table de base de données sont censés être uniques par n champs;
plusieurs ( deux ou plus ) demandes simultanées, traitées par des processus séparés chacun ( serveurs d'applications, serveurs de travail en arrière-plan ou tout ce que vous utilisez ), accédez à la base de données pour insérer le même enregistrement dans la table;
chaque processus en parallèle valide s'il existe un enregistrement avec les mêmes n champs;
la validation de chaque demande est réussie et chaque processus crée un enregistrement dans la table avec les mêmes données.
Pour éviter ce genre de comportement, il faut ajouter une contrainte unique à la table db. Vous pouvez le définir avec une
add_index
assistance pour un (ou plusieurs) champ (s) en exécutant la migration suivante:Attention : même après avoir défini une contrainte unique, deux requêtes simultanées ou plus essaieront d'écrire les mêmes données dans db, mais au lieu de créer des enregistrements en double, cela déclenchera une
ActiveRecord::RecordNotUnique
exception, que vous devrez gérer séparément:la source
Cela peut être fait avec une contrainte de base de données sur les deux colonnes:
add_index :friendships, [:user_id, :friend_id], unique: true
Vous pouvez utiliser un validateur de rails, mais en général, je recommande d'utiliser une contrainte de base de données.
Plus de lecture: https://robots.thoughtbot.com/validation-database-constraint-or-both
la source