2017-05-20 2 views
0

J'ai un problème avec le fait que mon schéma (qui a des contraintes pour les champs sous la forme d'enums, min et ainsi de suite, n'est pas respecté quand j'essaie d'écrire dans la base de données. créé un objet iwth erreurs mais il ne dit pas quoi que ce soit et juste insère le mauvais data.below est mon code: recipes.js:Validation du schéma, contraintes non honorées

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 

var schema = new Schema({ 
     name: {type:String, required:true},  
     category_name: [{ type: String, enum: [ "breakfast", "lunch","dinner"], required:true }], 
     difficulty_level: { type: String, enum: [ 'easy', 'medium', 'hard'], required:true }, 
     time_of_prep: { type: String, enum: [ '<=30 min', '1h-2h', 'more than 2h'], required:true }, 
     no_of_servings: { type: Number, min:1 , required:true},  
     ingredients_specified: [{ 
      ingredient: {type: String, required:true }, 
       amount: {type: String, required:true} 
     }], 
     description: {type:String, required:true}, 
     guide: {type:String, required:true} 
    }); 

    module.exports = mongoose.model('Recipe',schema); 

recipesSeeder.js:

var Recipe = require('../models/recipes'); 
var mongoose = require('mongoose'); 
mongoose.Promise = require('bluebird'); 
mongoose.connect('pathtodb'); 
var conn = mongoose.connection; 

var recipes=[ 
    new Recipe({ 
     name: 'TestName1', 
     category_name: 'lunch', 
     difficulty_level: 'easy', 
     time_of_prep: '<=30min', 
     no_of_servings: 5, 
     ingredient_specified: { 
      ingredient:'banana', 
      amount:'2 pieces' 
     }, 
     description: 'description1', 
     guide: 'guide1' 
    }), 
    new Recipe({ 
     name: ' ', 
     category_name: 'testingerrorcat', 
     difficulty_level: 'testingerrordiff', 
     time_of_prep: 'testingerrortime', 
     no_of_servings: 0, 
     ingredient_specified: { 
      ingredient:'ingredient2', 
      amount:'amount2' 
     }, 
     description: 'description2', 
     guide: 'guide2' 

    }), 
    new Recipe({ 
     name: 'TestName3', 
     category_name: 'lunch', 
     difficulty_level: 'easy', 
     time_of_prep: '<=30min', 
     no_of_servings: 5, 
     ingredient_specified: { 
      ingredient:'ingredient3', 
      amount:'amount3' 
     }, 
     description: 'description3', 
     guide: 'guide3' 
    }) 
]; 

var done = 0; 
for (var i = 0; i < recipes.length; i++){ 

    conn.collection('recipes2').save(recipes[i]); 
    done++; 
    if(done === recipes.length){ 
       console.log('data inserted'); 
       exit(); 
      } 
} 

function exit() { 
    mongoose.disconnect(); 
} 

Répondre

0

selon la validation mongoose documentation est un intergiciel et il est enregistré comme pré ('save') hook sur chaque schéma par défaut. Cela signifie que la validation est appliquée lorsque vous essayez d'appeler save, et non lors de l'initialisation. De plus, vous appelez save sur conn.collection ('recipes2') pas sur le modèle lui-même, donc il n'y a pas eu de validation.

La méthode appropriée consiste à appeler la fonction validate sur le modèle, qui renvoie un rappel. Dans le rappel de vérifier l'erreur, si aucune erreur, puis peut enregistrer sur le modèle pour stocker dans la base de données.

Quelque chose comme ça, j'ai remplacé votre for-loop par for-each par la façon.

recipes.forEach(function (recipe) { 
    recipe.validate(function(err) { 
     if (err) { 
      console.log(err);//don't save, do something with the error 
      return; 
     } 
     console.log("validation passsed"); 
     recipe.save(); 
    }); 

}); 

Voici une modification que j'ai apportée à votre schéma afin qu'il sache avec quelles collections il doit travailler.

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 

var schema = new Schema({ 
     name: {type:String, required:true},  
     category_name: [{ type: String, enum: [ 'breakfast', 'lunch','dinner'], required:true }], 
     difficulty_level: { type: String, enum: [ 'easy', 'medium', 'hard'], required:true }, 
     time_of_prep: { type: String, enum: [ '<=30min', '1h-2h', 'more than 2h'], required:true }, 
     no_of_servings: { type: Number, min:1 , required:true},  
     ingredients_specified: [{ 
      ingredient: {type: String, required:true }, 
       amount: {type: String, required:true} 
     }], 
     description: {type:String, required:true}, 
     guide: {type:String, required:true} 
    }); 

    module.exports = mongoose.model('Recipe',schema, 'recipes2'); //ADDED COLLECTION NAME HERE 

Cela dit, après que je rencontrais problème mineur dans votre schéma, vous avez « < = 30 min » défini, mais dans vos objets que vous avez « < = 30min » sans espace. C'est un problème mineur.

Un autre problème que je vois dans votre code est que dans votre boucle for, vous appelez save, qui est asynchrone. Votre code appellera save mais n'attendra pas qu'il se termine et passera simplement à autre chose. Cela signifie que vous pouvez en avoir terminé avec l'ensemble de votre boucle, puis appeler la fonction exit pour fermer la connexion, alors qu'elle n'a pas encore été enregistrée dans la base de données.

J'espère que ça aide.