J'ai un schéma de mangousage simple qui ressemble à ceci: Dans des circonstances normales, la table est unique sur Donc, essentiellement, je veux faire vérifier la vérification suivante avant qu'une sauvegarde est faite: p> Un moyen d'appliquer ce code ci-dessus est d'exécuter le code ci-dessus dans un crochet préaunaire. Mais, je me demandais simplement s'il y aurait une manière construite pour spécifier cela dans le schéma de mangouste elle-même? P> Merci pour l'aide! P> Solution: fort>
En plus de la solution gentiment fournie par @suleymansah ci-dessous, je pensais que je publierais ce que j'ai enfin fini par utiliser. P> (nom, type) code> donc l'utilisateur est donc l'utilisateur capable de stocker plusieurs types pour chaque fruit. Cependant, je souhaite permettre à l'utilisateur de stocker uniquement un code> si le nom
du nom code> du
fruit code> est
pomme code>. p>
const fruitSchema = new mongoose.Schema({
fruit: {
type: String
required: true,
async validate(name) {
if (name === 'apple') {
let fruit
try {
fruit = await Fruit.findOne({ name })
} catch (e) {
console.error('[Fruit Model] An error occurred during validation.')
console.error(e)
throw e // rethrow error if findOne call fails since fruit will be null and this validation will pass with the next statement
}
if (fruit) throw new Error(`A fruit for ${name} already exists.`)
}
},
type: {
type: String,
required: true
}
})
schema.index({ fruit: 1, type: 1 }, { unique: true })
const Fruit = mongoose.model('Fruit', fruitSchema)
3 Réponses :
Vous pouvez le faire comme ça avec Express, par exemple lors de la sauvegarde d'un nouveau fruit: Cela empêchera tout fruit avec le même nom de l'enregistrement de la base de données P> P >
Merci. C'est une façon d'y aller mais ne l'applique pas sur un niveau de schéma. Je pensais qu'un hook pré-sauvegarde serait probablement une meilleure option à cela, car cela garantirait cette exigence sur le niveau de DB. Vous suggérez-vous qu'il serait une meilleure pratique de l'appliquer au niveau du routeur?
Oui, je le fais comme ça et le suggère parce que, à mon avis, il s'agit d'une autre couche de vérifier toutes les commandes, pré-exigences avant d'économiser, ce qui constitue une meilleure conception et un meilleur schéma - comme son nom l'indique, devrait être composé du schéma - le plan des modèles.
J'ai compris. Merci! Marquant cela comme la réponse.
Je pense que c'est une requête similaire Vous devez ajouter index et le définir à unique restreindre pour stocker des valeurs en double dans mongodb P>
Eh bien, j'ai déjà défini un indice composé unique sur (nom, type). Le problème est que cela est censé être unique sur le nom, uniquement pour un certain sous-ensemble des rangées.
Cela ne fonctionnerait pas car il n'est pas unique dans certains cas comme mentionné.
Vous pouvez utiliser validateurs personnalisés comme ceci:
const schema = new mongoose.Schema({ name: { type: String, required: true }, type: { type: String, required: true, validate: { validator: async function() { if (this.name === "apple") { let doc = await this.constructor.findOne({ name: "apple" }); return Boolean(!doc); } }, message: props => "For apple only one type can be." } } });
Hé, c'était ce que je cherchais en fait. J'ai quelques validations synchrones sur le champ Type ainsi que bien. Comment ferais-je incorporer ces aussi dans le code? Merci pour ton aide! J'ai marqué le vôtre comme la réponse.
Salut, tu es la bienvenue. Je vous suggère de lire des documents de validation personnalisés de Mongoose et de mettre en œuvre vous-même, vous pouvez poser une nouvelle question si vous êtes bloqué.
J'ai lu via les documents et je suis à l'aide d'une fonction de validation comme celle-ci: jsfiddle.net/04o1Phly . Y a-t-il une différence entre celui-ci et celui que vous avez donné dans votre réponse? J'ai également remarqué que vous avez utilisé ceci.constructor.findone code> dans votre réponse plutôt que
fruit.findone code>. Une raison de cela?
À l'intérieur du schéma, nous n'avons pas accès à des fruits. J'ai donc utilisé cela.Constructeur pour renvoyer le modèle réel.
Il semble fonctionner pour moi. En ce sens, j'ai accès à cela. Étrange. Mais merci, c'est la voie à suivre. J'utilise JOI pour les validations avant de toute façon.
Eu une autre question rapide pour vous. Le attendre l'appel code> dans la validation doit être enveloppé dans un bloc de capture d'essai? Sinon, pourquoi?
@Philosophe Il serait certainement une bonne idée, j'ai sauté cela pour la simplicité.