2012-11-27 40 views
15

Tôi đang sử dụng sơ đồ này với mongoose 3.0.3 từ NPM:Mongoose xác nhận độc đáo loại lỗi

var schema = new Schema({ 

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

}); 

Nếu tôi cố gắng tiết kiệm một email đó là đã có trong db, tôi hy vọng sẽ có được một ValidationError như thế nào nếu một lĩnh vực required bị bỏ qua. Tuy nhiên, đây không phải là trường hợp, tôi nhận được MongoError: E11000 duplicate key error index.

Lỗi nào không phải là lỗi xác thực (xảy ra ngay cả khi tôi xóa bỏ duy nhất: đúng).

Bất kỳ ý tưởng nào tại sao?

+2

Lưu ý phụ: "npm mongoose mới nhất" có thể là vô nghĩa trong tuần/tháng/năm. Đặt phiên bản bạn đang sử dụng. – freakish

+2

Nó tiếp tục làm nó ngay cả sau khi bạn gỡ bỏ duy nhất: đúng bởi vì như alexjamesbrown nói, đặc điểm kỹ thuật đó tạo ra một chỉ số trên DB của bạn. DB và chỉ mục đó tồn tại cho đến khi bạn thả chỉ mục hoặc DB. Có thể bạn đã hiểu điều đó, nhưng tôi đã nhận ra rằng việc gọi điều đó có thể hữu ích cho ai đó. – juanpaco

Trả lời

21

Tôi thích đặt nó lên n cơ chế xác nhận con đường, như

UserSchema.path('email').validate(function(value, done) { 
    this.model('User').count({ email: value }, function(err, count) { 
     if (err) { 
      return done(err); 
     } 
     // If `count` is greater than zero, "invalidate" 
     done(!count); 
    }); 
}, 'Email already exists'); 

Sau đó, nó sẽ chỉ được gói gọn trong ValidationError và sẽ trở lại như là đối số đầu tiên khi bạn gọi validate hoặc save.

+0

Đây là câu trả lời đúng. Nó phải là trình xác thực tùy chỉnh cho đường dẫn, chứ không phải là chức năng lưu trước. – user3344977

+1

Điều này hoạt động nhưng bằng cách sử dụng this.model có thể ném một lỗi trong các tình huống nhất định khi điều này không đề cập đến một tài liệu/dụ của mô hình, nhưng bản thân mô hình thực tế. Cách an toàn để xử lý tất cả các tình huống và tránh ném một lỗi là sử dụng mongoose.model ('Người dùng', UserSchema) thay thế. – user3344977

+0

Điều này làm việc cho tôi, cảm ơn. –

10

này dự kiến ​​hành vi

Các unique: true tương đương với thiết lập một chỉ mục trong MongoDB như thế này:

db.myCollection.ensureIndex({ "email": 1 }, { unique: true }) 

Để làm kiểu này xác nhận sử dụng Mongoose (Mongoose gọi validation- phức tạp này tức là-bạn không chỉ xác nhận giá trị là số ví dụ), bạn cần phải kết nối với sự kiện lưu trước:

mySchema.pre("save",function(next, done) { 
    var self = this; 
    mongoose.models["User"].findOne({email : self.email},function(err, results) { 
     if(err) { 
      done(err); 
     } else if(results) { //there was a result found, so the email address exists 
      self.invalidate("email","email must be unique"); 
      done(new Error("email must be unique")); 
     } else { 
      done(); 
     } 
    }); 
    next(); 
}); 
+0

Đã thử phương pháp của bạn nhưng gặp sự cố khác: xem http://stackoverflow.com/questions/13582862/mongoose-pre-save-async-middleware-not-working-as-expected – Olivier

Các vấn đề liên quan