2

创建新记录时,我正在尝试验证Bookshelf.js中的电子邮件是否已存在验证。

我在这里找到了一个解决方案github但它不起作用,即使我尝试过Promise

User = bookshelf.Model.extend({
  tableName: 'users',
  initialize: function() {
    this.on('saving', this._assertEmailUnique);
  },
  _assertEmailUnique: function(model, attributes, options) {
    if (this.hasChanged('email')) {
      return this
        .query('where', 'email', this.get('email'))
        .fetch(_.pick(options, 'transacting'))
        .then(function (existing) {
          if (!existing) throw new Error('duplicate email');
        });
    }
  }
});

对于当前使用Joi的模型验证,看起来 Joi 也不支持对此进行自定义验证。我正在使用 Postgres 数据库。还有其他方法可以做到这一点..请帮助...

提前致谢..

4

2 回答 2

2

您的代码有两个错误阻止它工作:

  1. if (!existing) ...应该倒置,因为如果给定的电子邮件已经存在,您希望失败
  2. 查询this会将您的查询限制为当前记录,您需要从头开始查询,使用普通User

通过这些修复,您的代码将如下所示:

User = bookshelf.Model.extend({
  tableName: 'users',
  initialize: function() {
    this.on('saving', this._assertEmailUnique);
  },
  _assertEmailUnique: function(model, attributes, options) {
    if (this.hasChanged('email')) {
      return User
        .query('where', 'email', this.get('email'))
        .fetch(_.pick(options || {}, 'transacting'))
        .then(function(existing) {
          if (existing) {
            throw new Error('Duplicated email: User id #' + existing.id);
          }
        });
    }
  }
});
于 2016-07-06T08:56:07.750 回答
1

上设置唯一键约束email,然后在模型中,在它被违反时捕获它是更有效的。

例如,在您的数据库迁移方面做类似的事情

...
table.string('email').notNullable().unique();

然后覆盖save模型的方法并从那里抛出应用程序特定的错误,如下所示:

User = bookshelf.Model.extend({
  tableName: 'users',
  save: function () {
        return bookshelf.Model.prototype.save.apply(this, arguments)
        .catch((error) => {
            if (error.code === '23505') { //unique_violation code if using postgres db
                throw new errors.DuplicateUserEmail('User with the same email already exists');
            }

            throw error;
        });
    }
});
于 2018-10-25T08:49:28.180 回答