【问题标题】:Sequelize validation throwing errorSequelize 验证抛出错误
【发布时间】:2015-12-30 20:46:44
【问题描述】:

我正在尝试检查用户名是否唯一,并且我认为我需要对此进行自定义验证。我编写了以下代码,但不是在.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');
                        }
                    });
            }
        }
    },

【问题讨论】:

  • 有点过时,但您是否有理由不通过在 dbms 中使用唯一键约束来强制执行用户名?
  • 不知道怎么用,用这个库。

标签: database node.js model sequelize.js


【解决方案1】:

您正在进行的验证是异步的。您调用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();
                });
        }
    }
},

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

【讨论】:

  • 文档很好,我只是愚蠢!我收到 TypeError,显然 done 函数不存在。
  • 你是什么版本,我相信异步验证只存在于 2.0
  • 我现在已经更新到2.0,现在验证函数返回{fct: [Function] },我不知道如何处理它。
  • 啊,看来我现在不应该直接调用 validate 函数。我已经开始工作了,谢谢。
【解决方案2】:

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() 上的任何错误。 See this example in their codebase

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

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

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

【讨论】:

    【解决方案3】:

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

    Sequelizejs 有一个findOrCreate() 方法,可以在执行任何操作之前检查某事是否存在。

    非常有用的方法:)

    【讨论】:

      猜你喜欢
      • 2021-07-18
      • 2018-05-08
      • 1970-01-01
      • 2016-05-01
      • 2014-08-21
      • 1970-01-01
      • 2020-06-13
      • 2011-11-05
      • 1970-01-01
      相关资源
      最近更新 更多