【问题标题】:Mongoose custom validator: check if value exists in databaseMongoose 自定义验证器:检查数据库中是否存在值
【发布时间】:2017-12-11 02:54:27
【问题描述】:

我目前正在尝试将自定义验证器添加到我的架构中。由于某种原因,我无法查询数据库。有谁知道我的问题的解决方案?

这是架构:

var Portfolio = new Schema({
    title: {
        type: String,
        required: [true, 'Title is required']
    },
    thumbnail: {
        type: String,
        required: [true, 'Thumbnail is required'],
    },
    description: String,
    date: Date,
    images: [String],
    categories: [Schema.Types.ObjectId],
    order: Number,
    slug: {
        type: String,
        validate: {
            validator: slugExists,
            message: 'Slug already exists, choose a different title',
        }
    }
}, options);

这是检查数据是否存在的方法:

function slugExists(value) {
    this.model.count({slug: value}, function(err, count) {
        if (error) {
            return err;
        }
        return count > 0;
    });
}

当我运行应用程序时,我收到以下错误消息:

TypeError: this.model.count is not a function

我也尝试过使用以下内容:

mongoose.model['portfolio'].count(...)

但结果是一样的。

我已经尝试了两个小时来解决这个问题,甚至尝试了不同的方法(例如 pre hook)。但是将自定义验证直接添加到 Schema 感觉就像是最干净的条目。

希望你有一个解决方案。非常感谢!

杰弗里

【问题讨论】:

  • 嗯...为什么不在slug 上添加一个unique 索引?尽管如此,这个answer 可能会引导您到某个地方。你试过mongoose.model('portfolio').count(...) 吗?
  • 感谢您的回答米奇。可悲的是,这两种解决方案都不起作用。我不断收到以下错误:无法读取未定义的属性“计数”。

标签: mongoose mongoose-schema


【解决方案1】:

可以使用pre-save方法 考虑下面尝试在用户模型中验证用户名的示例:

   UserSchema.pre('save', function (next) {
   var self = this;
   mongoose.models["User"].findOne({username: self.username}, function (err, user) {
      if (!user) {
          next();
      } else {
          next(new Error("Username already exists!"));
      }
  });

【讨论】:

  • 感谢您提出解决方案。不过,我不想使用 pre 钩子,因为那样我必须考虑另一种处理错误消息的方法(如您在我的示例中所见,我正在使用 Mongoose 的自定义消息来处理错误)。
  • 通过使用上述方法,您也会得到相同的自定义错误。您也可以在自定义函数中使用钩子函数。
  • 感谢您的回复。最终我找到了我正在寻找的解决方案。我仍然很好奇您如何在预挂钩中构建相同的自定义错误。我会调查的!
【解决方案2】:

在测试不同的解决方案时,我发现一篇回答了我的问题的帖子 (https://stackoverflow.com/a/26268156/8267696)。

这是我正在寻找的解决方案:

function slugExists(value, callback) {
    this.constructor.count({slug: value}, function(err, count) {
        if (err) {
            next(err);
        }
        callback(count === 0);
    });
}

Portfolio.pre('validate', function(next) {
    this.slug = slugify(this.title);
    next();
});

旁注:slug 将根据标题生成。这就是为什么我必须使用“验证”预挂钩,以便在验证之前已经设置了 slug(否则验证器将被忽略,因为它没有任何值并且不是必需的)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-24
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 2018-06-02
    相关资源
    最近更新 更多