使用预保存挂钩时如何检查数据库的值?

时间:2013-12-05 20:33:43

标签: node.js mongoose

在用户架构上,我想在保存之前检查指定商店是否已存在指定的电子邮件。

var UserSchema = new Schema({
    _shop: {
        type: Schema.Types.ObjectId,
        ref: 'Shop',
        required: true
    },
    email: String,
    //...
});

UserSchema.pre('save', function(next) {
    if (!this.isNew) return next();
    // How to do use the static method isThatEmailFreeForThisShop here?
});

UserSchema.statics.isThatEmailFreeForThisShop = function(email, shop_id, cb) {
    this.find({email: email, _shop: shop_id}, function(err, users) {
        // ...
    });
});

只要来自不同的商店,可能会有不同的用户使用相同的电子邮件。 我不知道如何在预保存挂钩中使用静态方法... 谢谢!

1 个答案:

答案 0 :(得分:1)

您已在某处创建了用户模型实例(我将其称为User):

var User = mongoose.model('user', UserSchema);

因此,isThatEmailFreeForThisShop模型上提供了User函数:

User.isThatEmailFreeForThisShop(...)

来自你的保存钩子:

UserSchema.pre('save', function(next) {
    if (!this.isNew) return next();
    User.isThatEmailFreeForThisShop(this.email, this._shop, 
        function(err, result) {
            if (result) { // found
               // do something
               return next({ error: "duplicate found" });
            }
            return next();
    });
});

您可能还想切换到使用前validate而不是save

我希望您的功能isThatEmailFreeForThisShop在找到结果时调用cb参数。

您可能会使用findOnereference)而不是find。鉴于仍然存在竞争条件,您希望将add an index作为复合索引emailshop_id并将unique属性设置为true,以防止重复项隐藏(然后,您需要处理模型实例上的save可能引发错误的事实。)

UserSchema.statics.isThatEmailFreeForThisShop = function(email, shop_id, cb) {
    this.findOne({email: email, _shop: shop_id}, function(err, user) {
        // ...
        cb(err, user != null);
    });
});