【问题标题】:Validation of schema, not honored constraints验证模式,不遵守约束
【发布时间】:2017-05-21 01:28:11
【问题描述】:

我有一个问题,即我的架构(对枚举、min 等形式的字段有约束)在我尝试写入数据库时​​没有得到尊重。我创建了一个有错误的对象,但它什么也没说,只是插入了错误的数据。下面是我的代码: 食谱.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();
}

【问题讨论】:

    标签: mongodb mongoose mongoose-schema


    【解决方案1】:

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

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

    像这样,我顺便用 for-each 替换了你的 for-loop。

    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
    

    话虽如此,在此之后我在您的架构中遇到了小问题,您定义了 '

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

    我希望它有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-21
      • 2015-08-17
      • 1970-01-01
      • 2019-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多