6
votes

Comment gérer un champ unique en voiles?

J'ai défini un champ unique dans mon modèle, mais quand j'ai essayé de tester, il semble que cela ne soit pas vérifié par Sails car je reçois une erreur (e_unknown) :: rencontre une erreur inattendue: MONGOERROR: EM11000 Duplicate Key Error Index: Code> Au lieu d'une navigation ValidationError.

Quelle est la meilleure façon de gérer un champ unique dans des voiles? P>

// model/User.js
module.exports{
attributes: {
  email: {required: true, unique: true, type: 'email' },
  ....
}
// in my controller
User.create({email: 'hello@gmail.com'}).then(...).fail(....)
User.create({email: 'hello@gmail.com'}).then(...).fail(// throws the mongo error ) 
// and same goes with update it throws error


3 commentaires

Pouvons-nous obtenir du code?


@Internalfx J'ai mis à jour la question à inclure des codes. Merci


@ginad Veuillez marquer votre solution préférée comme la réponse correcte.


6 Réponses :


5
votes

Vous essayez de créer deux utilisateurs avec la même adresse e-mail après avoir défini le courrier électronique en tant que champ unique.

Vous pouvez peut-être interroger pour un utilisateur par cette adresse électronique - s'il existe déjà une erreur ou une mise à jour Utilisateur. xxx

voiles .js & mongodub: index d'erreur clé en double

Il y a aussi un peu intéressant sur les propriétés du modèle uniques dans les Sails.js Docs https://github.com/ballderdashy/waterline#indexing

ÉDITER: Tiré de http://sailsjs.org/#!Documentation/models < p> validations disponibles sont les suivants:

vide, obligatoire, noteur, indéfini, chaîne, alphanumérique, numérique, alphanumérique, email, URL, urlish, IP, IPv4, IPv6, CreditCard, uuid, uuidv3, uuidv4, int, entier, nombre, fini, décimal, flotteur, fausse, sothnull, null, notnull, booléen, tableau, date, hexadécimale, heexcolor, minuscule, majuscule, après, avant, est, regex, non, NOTREGEX, égale, contient, NotContains, Len, In, Noter, Max, Min, Minlength, Maxlength


2 commentaires

Merci, oui, je pense à utiliser cette méthode aussi mais je suis juste curieux s'il y a une meilleure façon de générer une validationError.


J'ai mis à jour mon message pour inclure la liste des validations effectuées par Sailsjs. Unique n'est pas l'un d'entre eux - cela vous est donc laissé à vous d'interpréter la réponse de MongoDB lorsque vous essayez de créer un enregistrement contenant un email unique.



10
votes

Le attribut unique actuellement crée uniquement un index unique dans MongoDB .

Vous pouvez utiliser le avantValidate () rappel pour rechercher un enregistrement existant avec cet attribut et enregistrer le résultat Une variable de classe.

Cette approche garantit que votre modèle renvoie une erreur de validation appropriée pouvant être évaluée par des clients. xxx

edit < / strong>

Comme Thinktt a souligné, il y avait une erreur dans ma solution précédente qui a rendu la valeur par défaut imageMail inutile car il est défini dans la déclaration modèle elle-même et ne peut donc pas être référencé dans le code du modèle. J'ai édité ma réponse en conséquence, merci.


0 commentaires

0
votes

@tvollstedt Votre réponse a fonctionné comme un charme, et d'ailleurs est le moyen le plus élégant de gérer "l'unicité" à Sailsjs jusqu'à présent.

Merci! P>

Voici mes deux cents pour ajouter des messages de validation personnalisés à l'aide de "Sails-validation-messages": p>

p>

module.exports = {
	create:function(req, res){
    var values = req.allParams();
	Application.create({
	  email:values.email,
	  firstname:values.firstname,
	  lastname:values.lastname,
	  _csrf: values.csrf
	})
	exec(function created (err, values) {
      if(err) {
		console.log(err);
		if(err.invalidAttributes) {
          validator = require('sails-validation-messages');
		  err.invalidAttributes = validator(Application, err.invalidAttributes);
		    return res.negotiate(err);
	      }
	    }
	  });
	}
};


0 commentaires

2
votes

Les solutions de @tvollstedt et David ont posté le travail, mais il y a un gros problème avec ce code. Je me luttais avec elle toute la journée pour que je pose cette réponse légèrement modifiée. Je voudrais juste commenter mais je n'ai pas encore les points. Je vais volontiers supprimer cette réponse si elles peuvent mettre à jour le leur, mais j'aimerais vraiment aider quelqu'un qui avait les mêmes problèmes que j'ai eu.

Le problème avec le code ci-dessus, à l'aide du validateur personnalisé, vous ne pouvez pas accéder à l'attribut "uniqueemail" des propriétés de la manière dont les deux solutions précédentes tentent de faire. La seule raison pour laquelle il travaille dans ces solutions est du fait qu'ils jettent par inadvertance "uniqueemail" dans l'espace mondial.

Ce qui suit est une légère modification du code TVOLLSTEDT qui n'utilise pas l'espace global. Il définit l'un des illustrations uniques à l'extérieur du mode modual.exports, par conséquent étant scopé uniquement au module mais accessible tout au long du module.

Il peut y avoir une meilleure solution, mais c'est le meilleur que je pourrais proposer avec une solution minimale d'une solution autrement élégante. xxx


0 commentaires

0
votes

La bonne façon de faire cela !!!

module.exports = {
schema: true,
migrate: 'safe',
tableName: 'users',
autoCreatedAt: false,
autoUpdatedAt: false,
adapter: 'mysql',

/**
 * Custom validation types
 */
types: {
    uniquePhone: function(value) {
        return value!=='_unique';
    }
},
attributes: {
    id: {
        type: 'integer',
        primaryKey: true,
        unique: true,
        autoIncrement: true
    },
    email: {
        type: 'email'
    },
    first_name: {
        type: 'string'
    },
    last_name: {
        type: 'string'
    },
    phone: {
        type: 'string',
        required: true,
        uniquePhone: true
    }

},
/**
 * Lifecycle Callbacks
 */
beforeValidate: function(values, cb) {
    Users.findOne({phone: values.phone}).exec(function(err, record) {
        // do whatever you want check against various scenarios
        // and so on.. 
        if(record){
            values.phone='_unique';
        }
        cb();
    });
}


0 commentaires

0
votes

Dans la dernière version de Sails v1.2.7, les rappels ne fonctionnent plus. Si vous rencontrez un problème dans lequel l'unicité ne fonctionne pas sur vos modèles - comme je l'ai fait avec Sails-Mongo, vous auriez besoin de la configurer manuellement dans vos contrôleurs.

Voici un exemple P>

//SIGNUP
create: async (req, res) => {
    const { name, email, password } = req.body;
    try {
      const userExists = await sails.models.user.findOne({ email });
      if (userExists) {
        throw 'That email address is already in use.';
      }
}


0 commentaires