这个Mongoose独特的预保存验证在做错什么? [英] What am I doing wrong in this Mongoose unique pre-save validation?
问题描述
我正在尝试创建一个具有唯一用户名的用户模型.这是它的代码:
I'm trying to create a User model, that has an unique username. Here's the code for it:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: String,
password: String,
});
UserSchema.virtual("password_confirmation").get(function() {
return this.pw_conf;
}).set(function(value) {
this.pw_conf = value;
});
UserSchema.path("username").required(true);
UserSchema.path("password").required(true);
UserSchema.pre("save",function(next, done) {
var self = this;
mongoose.models["User"].findOne({username : self.username},function(err, user) {
if(user) {
self.invalidate("user","username must be unique");
}
done();
});
next();
});
UserSchema.pre("save",function(next) {
if(this.pw_conf !== this.password) {
next(new Error("Must specify the password confirmation"));
}
else {
next();
}
});
module.exports = mongoose.model("User",UserSchema);
我也在测试唯一性是否有效:
I was also testing to see if the uniqueness works:
var User = require("./users"),
mongoose = require("mongoose");
var u = new User();
mongoose.connect('mongodb://localhost/my_database');
u.username = "me";
u.password = "password";
u.password_confirmation = "password";
u.save(function(err) {
if(err) {
console.log(err);
}
mongoose.disconnect();
});
问题是,不是.每次运行代码时,都会创建一个新对象.我知道,可能还有其他方法可以确保唯一性,但是我想以这种方式做到这一点.处理findOne
方法的结果后,是否应该不调用done
?我打错电话next
吗?
Problem is, it doesn't. Each time I run the code, I get a new object created. I am aware that there are probably other ways of ensuring uniqueness, but I'd like to do it in this way. Shouldn't I be calling done
after I handle the result of the findOne
method? Am I calling next
wrong?
推荐答案
要使用并行中间件(带有next
和done
参数),您需要将true
作为第二个参数传递.
To use parallel middleware (with next
and done
parameters), you need to pass true
as the second parameter.
除此之外,还有两种可能性:
Beyond that, there are two possibilities:
您的self.invalidate
调用应该引用"username"
而不是"user"
.如果仍不能解决问题,如果要中止保存操作,可以通过将Error对象传递给done
来明确地使事情失败:
Your self.invalidate
call should be referencing "username"
instead of "user"
. If that doesn't fix it, you can fail things explicitly by passing an Error object to done
if you want to abort the save operation:
UserSchema.pre("save", true, function(next, done) {
var self = this;
mongoose.models["User"].findOne({username: self.username}, function(err, user) {
if(err) {
done(err);
} else if(user) {
self.invalidate("username", "username must be unique");
done(new Error("username must be unique"));
} else {
done();
}
});
next();
});
这篇关于这个Mongoose独特的预保存验证在做错什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!