在这个猫鼬独特的保存前验证中,我做错了什么

What am I doing wrong in this Mongoose unique pre-save validation?

本文关键字:验证 什么 错了 保存      更新时间:2023-09-26

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

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);

我还在测试唯一性是否有效:

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吗?

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

要走的路。它使用实际的 MongoDb 索引来确保您的字段是唯一的。无需.pre中间件。

享受!

要使用并行中间件(带有nextdone参数),您需要将true作为第二个参数传递。

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

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

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();
});
有一个

非常好的猫鼬插件,非常易于安装和使用。文档非常好,它第一次对我有用。

但是重新保存存在问题。

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

您是否考虑过使用异步验证器来捕获错误?

UserSchema.path('username').validate(function (value, done) {
  User.count({ username: value }, function (error, count) {
    // Return false if an error is thrown or count > 0
    done(!(error || count));
  });
}, 'unique');