【问题标题】:Bookshelf.js unique email validation before create new recordBookshelf.js 在创建新记录之前进行独特的电子邮件验证
【发布时间】:2016-11-04 00:48:39
【问题描述】:

在创建新记录时,我正在尝试验证电子邮件在 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 数据库。还有其他方法可以做到这一点..请帮助...

提前谢谢..

【问题讨论】:

    标签: node.js validation express bookshelf.js joi


    【解决方案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;
            });
        }
    });
    

    【讨论】:

      【解决方案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);
                }
              });
          }
        }
      });
      

      【讨论】:

      • 感谢这个工作,一件事我已经从fetch() 方法中删除了这个_.pick(options || {}, 'transacting'),然后只执行查询.. 否则很好
      • @flaviodesousa 我正在使用带有 hapi-bookshelf-models 插件的书架。正如您所提到的,我无法访问 _assertEmailUnique 方法中的模型。我只是收到一个错误"User.query is not a function"。有解决办法吗?
      猜你喜欢
      • 1970-01-01
      • 2021-09-21
      • 2019-02-13
      • 2012-01-10
      • 2013-03-01
      • 1970-01-01
      • 2020-10-20
      • 2021-09-22
      • 1970-01-01
      相关资源
      最近更新 更多