Rails: Valide une combinaison unique de 3 colonnes

Salut je ne veux pas valider la combinaison unique de 3 colonnes dans ma table.

Disons que j’ai un tableau appelé voitures avec les valeurs: marque,: nom_modèle et: type_combustible.

Ce que je veux ensuite, c’est valider si un enregistrement est unique en fonction de la combinaison des trois. Un exemple:

brand model_name fuel_type Audi A4 Gas Audi A4 Diesel Audi A6 Gas 

Tout devrait être valide. Mais un autre enregistrement avec «Audi, A6, Gas» ne devrait PAS être valide.

Je connais cette validation, mais je doute qu’elle fasse réellement ce que je veux.

  validates_uniqueness_of :brand, :scope => {:model_name, :fuel_type} 

Il y a une erreur de syntaxe dans votre extrait de code. La validation correcte est la suivante:

 validates_uniqueness_of :car_model_name, :scope => [:brand_id, :fuel_type_id] 

ou même plus court en rbuy 1.9.x:

 validates_uniqueness_of :car_model_name, scope: [:brand_id, :fuel_type_id] 

avec des rails 4, vous pouvez utiliser:

 validates :car_model_name, uniqueness: { scope: [:brand_id, :fuel_type_id] } 

avec des rails 5, vous pouvez utiliser

 validates_uniqueness_of :car_model_name, scope: %i[brand_id fuel_type_id] 

Cela dépend de vos besoins, vous pouvez également append une contrainte (dans le cadre de la migration de la création de la table ou en tant que partie distincte) au lieu de la validation du modèle:

 add_index :the_table_name, [:brand, :model_name, :fuel_type], :unique => true 

L’ajout de la contrainte unique au niveau de la firebase database est logique, dans le cas où plusieurs connexions à la firebase database effectuent des opérations d’écriture en même temps.

Je ferais comme ça:

 validates_uniqueness_of :model_name, :scope => {:brand_id, :fuel_type_id} 

parce que cela a plus de sens pour moi:

  • il ne devrait pas y avoir de “noms de modèle” en double pour la combinaison de “marque” et de “type de carburant”,
  • il ne devrait pas y avoir de “marques” dupliquées pour la combinaison du “nom du modèle” et du “type de carburant”

mais c’est une opinion subjective.

Bien sûr, si la marque et fuel_type sont des relations avec d’autres modèles (sinon, il suffit de supprimer la partie “_id”). Avec la validation d’unicité, vous ne pouvez pas vérifier les colonnes non-db, vous devez donc valider les clés étrangères dans le modèle.

Vous devez définir quel atsortingbut est validé – vous ne validez pas tous en même temps, si vous le souhaitez, vous devez créer une validation distincte pour chaque atsortingbut, de sorte que lorsque l’utilisateur commet une erreur et tente de créer forme près du champ invalide.

To Rails 4 le code correct avec un nouveau motif de hachage

 validates :column_name, uniqueness: {scope: [:brand_id, :fuel_type_id]} 

L’utilisation de cette méthode de validation conjointement avec ActiveRecord::Validations#save ne garantit pas l’absence d’insertions d’enregistrement en double, car les contrôles d’unicité au niveau de l’application sont insortingnsèquement prédisposés aux conditions de concurrence.

Cela pourrait même arriver si vous utilisez des transactions avec le niveau d’isolation “sérialisable”. La meilleure façon de contourner ce problème consiste à append un index unique à la table de firebase database à l’aide d’ ActiveRecord::ConnectionAdapters::SchemaStatements#add_index . Dans les rares cas où une situation de concurrence se produit, la firebase database garantira l’unicité du champ.