我在Mongoose独特的预保存验证中做错了什么?

Geo*_*Geo 23 javascript mongoose node.js

我正在尝试创建一个具有唯一用户名的用户模型.这是它的代码:

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);
Run Code Online (Sandbox Code Playgroud)

我也在测试是否有独特性:

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();
});
Run Code Online (Sandbox Code Playgroud)

问题是,它没有.每次运行代码时,我都会创建一个新对象.我知道可能有其他方法可以确保唯一性,但我想以这种方式做到这一点.done在处理findOne方法的结果后,我不应该打电话吗?我打电话next错了吗?

rdr*_*rey 33

http://mongoosejs.com/docs/api.html#schematype_SchemaType-unique是要走的路.它使用实际的MongoDb索引来确保您的字段是唯一的.不需要.pre中间件.

请享用!

  • 是的但没有自定义错误消息..并且没有办法在同一文档上的2个不同的唯一错误之间产生差异.请参阅https://groups.google.com/d/msg/mongoose-orm/BX7kz0BwLjk/JWuvD_p4hYcJ (7认同)
  • +1为@YvesM.并且根据Mongoose文档说:"注意:违反约束**在保存时从MongoDB**返回E11000错误,**不是Mongoose验证错误**." (2认同)

Joh*_*yHK 29

要使用并行中间件(使用nextdone参数),您需要传递true第二个参数.

除此之外,有两种可能性:

你的self.invalidate电话应该是引用"username"而不是"user".如果这不能解决问题,done如果要中止保存操作,则可以通过传递Error对象来显式失败:

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();
});
Run Code Online (Sandbox Code Playgroud)


tho*_*ter 5

有一个非常好的猫鼬插件,非常容易安装和使用.文档非常好,第一次对我有用.

但重新储蓄存在问题.

https://npmjs.org/package/mongoose-unique-validator