2014-10-07 68 views
0

我想爲Mongoose創建一個驗證程序,如果此行已存在,導致.save()失敗。此刻我的驗證看起來有點像這樣(咖啡):模型預檢中的消防貓鼬驗證失敗

model.schema.path('email').validate (email) => 
    return email? and email.length > 0 
, 'BLANK_EMAIL' 

然而,他們是同步的,因此具有@model.find檢查長度內就不會工作。我正在考慮使用類似於下面的僞代碼的東西,但我不知道是否有可能,或者是否有更簡單的方法可以遵循我已經使用的相同的貓鼬驗證模式。謝謝!

model.schema.pre 'save', (next) -> 
    self = @ 
    model.find {email: self.email}, (err, rows) -> 
    if rows.length 
     # This bit is the pseudo-code: 
     model.schema.path('email').validate false 
    next() 

回答

1

http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate

schema.path('email').validate(function (value, respond) { 
    mongoose.model("user").count({email: this.email}, function(err, num) { 
    respond(!(err || num)); // validation failed 
    }) 
}, '{PATH} failed validation.'); 

您可能要檢查email: this.email, _id: {$ne: this._id},根據您的需要。上面的代碼片段沒有經過測試,但您可以瞭解一般想法。

具有兩個參數(值爲&回調)的驗證器異步運行,而不是帶有一個參數(值)的驗證器,該驗證器必須返回一個布爾值。該回調會收到一個布爾值,表示應拋出該錯誤。 AFAIK,您無法將Error實例傳遞給回調。

+0

啊,一個回調參數!我沒有看到 - 我不知道這是否僅僅是我或者Mongoose文檔不是最容易遍歷的。謝謝,我會試一試。 – 2014-10-07 12:03:08

+0

Ps。我在我的問題中得到了代碼,實際上只是在執行'next(new Error('Email failed validation'))',但我想象Mongoose異步驗證方法更清晰並且可能帶來了更多好處。 – 2014-10-07 12:04:11

+0

是的,你也可以在預保存鉤子中傳遞一個'Error',但我更喜歡在驗證器中做一些事情;你將能夠執行'if(error instanceof MongooseValidationError)'並相應地處理錯誤。但是,再次,您的替代方法沒有任何問題。 – RikkusRukkus 2014-10-07 12:23:14