验证架构,而不是尊重约束

时间:2017-05-20 16:02:33

标签: mongodb mongoose mongoose-schema

我遇到的问题是,当我尝试在数据库中写入时,我的模式(以enums,min等形式对字段进行约束)没有得到尊重。我创建了一个错误的对象,但它没有说什么,只是插入错误的数据。下面是我的代码: recipes.js:

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();
}

1 个答案:

答案 0 :(得分:0)

根据mongoose documentation验证是一个中间件,默认情况下它被注册为每个模式的前(&#39; save&#39;)挂钩。这意味着当您尝试在其中调用save时,将应用验证,而不是在初始化时。你也在调用conn.collection(&#39; recipes2&#39;)而不是模型本身,因此没有进行验证。

正确的方法是在模型上调用validate函数,该函数返回回调。在回调中检查错误,如果没有错误,则可以调用保存模型以存储到数据库中。

像这样的东西,我顺便用for-for替换你的for循环。

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();
    });

});

以下是我对您的架构所做的修改,以便它知道需要使用哪些集合。

 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

这就是说,在此之后我在你的架构中遇到了一些小问题,你有&#39;&lt; = 30分钟&#39;已定义,但在您的对象中,您有&#39;&lt; = 30min&#39;没有空间。这是一个小问题。

我在你的代码中看到的另一个问题是你的for循环中,你正在调用save,这是异步的。您的代码将调用save但不会等待它完成,只需继续。 这意味着您可以完成整个循环,然后调用exit函数来关闭连接,但它还没有实际保存在数据库中。

我希望它有所帮助。