创建新记录时,我在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数据库。还有其他方法可以做..请帮忙......
提前致谢..
答案 0 :(得分:2)
您的代码有两个错误阻止它工作:
if (!existing) ...
应该被颠倒,因为如果给定的电子邮件已经存在,您想要失败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);
}
});
}
}
});
答案 1 :(得分: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;
});
}
});