web-dev-qa-db-fra.com

Rendre un champ unique dans ecto

Comment faire un champ unique in ecto?

Je pensais que c'était la même chose que l'enregistrement actif dans Ruby, mais il semble que ce ne soit pas

31
ardhitama

Vous souhaitez utiliser nique_constraint/ . Ce n'est pas comme Active Record car il utilise la base de données pour garantir l'unicité. Active Record ferait une requête pour les enregistrements avec la même valeur et si certains étaient retournés, il échouerait. Cela a une condition de concurrence où, si une valeur est insérée entre l'extraction pour vérifier l'unicité et l'insertion de votre enregistrement, vous vous retrouverez avec des données en double ou une erreur sera déclenchée (selon qu'un index est défini sur la base de données ou non. unique_constraint/3 n'a pas cette condition de concurrence.

Une chose à noter est que, puisque l'unicité n'est pas connue jusqu'à ce qu'une insertion soit tentée, la contrainte unique se produira après vos validations. Il n'est pas possible d'afficher simultanément les erreurs de validation et de contrainte.

La base de données que vous utilisez doit également prendre en charge des contraintes uniques. Ils ne fonctionneront pas avec SQLite. Vous pouvez en savoir plus sur le problème GitHub .

Dans votre migration:

create unique_index(:users, [:email])

Puis dans votre modèle:

cast(user, params, ~w(email), ~w())
|> unique_constraint(:email)

Il convient de noter qu'Ecto fournissait un validate_unique/3 fonction qui fonctionnait en effectuant une requête sur la base de données, mais elle était déconseillée au profit de unique_constraint/3 Dans version 0.16.

65
Gazler