Bookshelf.js 创建新记录前唯一的电子邮件验证

Bookshelf.js unique email validation before create new record

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

我在这里找到了一个解决方案github but its not working, even i tried with 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 数据库。还有其他方法吗..请帮忙...

提前致谢..

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

  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);
          }
        });
    }
  }
});

更有效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;
        });
    }
});