2012-11-27 92 views
19

從隨訪:Mongoose unique validation error type貓鼬pre.save()異步中間件工作不正常

我使用這個模式與mongoose 3.0.3從NPM:

var schema = new Schema({ 

    _id: Schema.ObjectId, 
    email: {type: String, required: true, unique: true} 

}); 

有了這個中間件從獲得validationError unique:true

schema.pre("save", function(next, done) { 
    var self = this; 

    model.findOne({email : this.email}, 'email', function(err, results) { 
     if(err) { 
      done(err); 
     } else if(results) { 
      console.warn('results', results); 
      self.invalidate("email", "email must be unique"); 
      done(new Error("email must be unique")); 
     } else { 
      done(); 
     } 
    }); 

    next(); 
}); 

但是,它不起作用!

Users.create()仍然會返回一個MongoError: E11000 duplicate key error indexconsole.warn()只在此之後被調用。

根據文檔調用所有中間件done()之前,不應調用保存操作,我應該收回驗證錯誤。

它看起來像done()行爲沒有按預期工作,

任何想法,爲什麼?

回答

37

您使用的是平行中間件回調函數(既nextdone),但因此它使用串行規則,你不設置平行國旗在schema.pre參數。

因此,無論在您的通話平行標誌:

schema.pre("save", true, function(next, done) { ... 

,或者切換到串行中間件回調風格,如果這就是你所需要的呢:

schema.pre("save", function(next) { 
    var self = this; 

    model.findOne({email : this.email}, 'email', function(err, results) { 
     if(err) { 
      next(err); 
     } else if(results) { 
      console.warn('results', results); 
      self.invalidate("email", "email must be unique"); 
      next(new Error("email must be unique")); 
     } else { 
      next(); 
     } 
    }); 
}); 
+0

這是否適用於什麼版本的貓鼬的?我無法在您的代碼片段中使用的'schema.pre'的此並行簽名中找到任何文檔。 –

+1

@PeterLyons並行選項至少已經回到2.x。有關文檔,請參閱http://mongoosejs.com/docs/middleware.html。 – JohnnyHK

+0

@JohnnyHK我可以在next()中發送狀態碼嗎?如果我想拒絕請求,那不是將請求保存在數據庫中,併發送狀態碼?可能嗎? – nirvair