Database Sequelize验证抛出错误

Database Sequelize验证抛出错误,database,node.js,model,sequelize.js,Database,Node.js,Model,Sequelize.js,我试图检查用户名是否唯一,我想我需要一个自定义验证。我已经编写了以下代码,但是它没有在.validate()返回的数组中返回错误,而是抛出错误,这不是文档中描述的行为,也不是我想要的 var User = sequelize.define('User', { username: { type: DataTypes.STRING, validate: { isUnique: function (username) {

我试图检查用户名是否唯一,我想我需要一个自定义验证。我已经编写了以下代码,但是它没有在
.validate()
返回的数组中返回错误,而是抛出错误,这不是文档中描述的行为,也不是我想要的

var User = sequelize.define('User', {
    username: {
        type: DataTypes.STRING,
        validate: {
            isUnique: function (username) {
                User.find({ where: { username: username }})
                    .done(function (err, user) {
                        if (err) {
                            throw err;
                        }

                        if (user) {
                            throw new Error('Username already in use');
                        }
                    });
            }
        }
    },

您正在进行的验证是异步的。调用
User.find
方法,然后返回验证方法。Sequelize无法知道您正在验证中执行异步操作,除非您这样告诉它。一旦find调用完成,您就会抛出错误,但验证已经完成,因此没有代码捕获该错误,这意味着抛出错误并导致应用程序崩溃

告诉sequelize您正在执行异步操作的方法是将第二个参数带到您的函数中,这是一个回调。如果在没有任何参数的情况下调用回调,则验证成功;如果为回调提供参数,则验证失败

var User = sequelize.define('User', {
username: {
    type: DataTypes.STRING,
    validate: {
        isUnique: function (username, done) {
            User.find({ where: { username: username }})
                .done(function (err, user) {
                    if (err) {
                        done(err);
                    }

                    if (user) {
                        done(new Error('Username already in use'));
                    }

                    done();
                });
        }
    }
},

请您指出文档中误导您的部分,然后我们希望能够纠正它:)

Sequelize支持Promise风格的异步操作。特别是Bluebird.js库。只需将函数更改为专门使用
Promise->next()
模式

var User = sequelize.define('User', {
   username: {
    type: DataTypes.STRING,
    validate: {
        isUnique: function (username) {
            User.find({ where: { username: username }})
                .then(function (user) {
                    if (user) {
                        throw new Error('Username already in use');
                    }
                });
        }
    }
},
这也将为您处理
User.find()
上的任何错误。

当然,处理唯一约束的最简单方法是在字段定义本身上设置
unique:true

var User = sequelize.define('User', {
  username: {
    type: DataTypes.STRING,
    unique: true
  },

但这需要您使用Sequelize创建表,或者已经有一个具有唯一约束集的表。

这个问题得到了一个有效的答案,解释了验证选项是如何工作的。但是在这种情况下,您不必检查用户是否独立存在

Sequelizejs有一个方法,在做任何事情之前检查是否存在某些事情


非常有用的方法:)

文档很好,我只是太傻了!我得到了一个TypeError,显然done函数不存在。您使用的是什么版本,我相信异步验证只在2.0中存在。我现在已经更新到2.0,现在验证函数返回
{fct:[function]}
,我不确定如何处理它。啊,看起来我现在不应该直接调用验证函数。我现在可以使用了,谢谢。有点不太好,但是有没有理由不在dbms中使用唯一键约束来强制使用用户名?不知道如何使用这个库。