Javascript sequelize.js自定义验证程序,检查唯一用户名/密码
假设我定义了以下自定义验证器函数:Javascript sequelize.js自定义验证程序,检查唯一用户名/密码,javascript,node.js,orm,sequelize.js,Javascript,Node.js,Orm,Sequelize.js,假设我定义了以下自定义验证器函数: isUnique: function () { // This works as expected throw new Error({error:[{message:'Email address already in use!'}]}); } 但是,当我尝试查询数据库时,遇到了以下问题: isUnique: function (email) { // This doesn't work var User = seqeulize.import('/pa
isUnique: function () { // This works as expected
throw new Error({error:[{message:'Email address already in use!'}]});
}
但是,当我尝试查询数据库时,遇到了以下问题:
isUnique: function (email) { // This doesn't work
var User = seqeulize.import('/path/to/user/model');
User.find({where:{email: email}})
.success(function () { // This gets called
throw new Error({error:[{message:'Email address already in use!'}]}); // But this isn't triggering a validation error.
});
}
如何在自定义验证器中查询ORM并根据ORM的响应触发验证错误?即使找不到用户,也会调用成功回调。您必须检查函数是否将用户作为参数传递:
isUnique: function (email) {
var User = seqeulize.import('/path/to/user/model');
User.find({where:{email: email}})
.success(function (u) { // This gets called
if(u){
throw new Error({error:[{message:'Email address already in use!'}]}); // But this isn't triggering a validation error.
}
});
}
下面是一个功能正常的
isUnique
验证回调的简化示例(从SequelizeJS v2.0.0开始工作)。我添加了注释来解释重要的部分:
var UserModel = sequelize.define('User', {
id: {
type: Sequelize.INTEGER(11).UNSIGNED,
autoIncrement: true,
primaryKey: true
},
email: {
type: Sequelize.STRING,
validate: {
isUnique: function(value, next) {
UserModel.find({
where: {email: value},
attributes: ['id']
})
.done(function(error, user) {
if (error)
// Some unexpected error occured with the find method.
return next(error);
if (user)
// We found a user with this email address.
// Pass the error to the next method.
return next('Email address already in use!');
// If we got this far, the email address hasn't been used yet.
// Call next with no arguments when validation is successful.
next();
});
}
}
}
});
module.exports = UserModel;
使用Sequelize 2.0,您需要捕获验证错误 首先,使用自定义验证器定义用户模型:
var User = sequelize.define('User',
{
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
isUnique: function (value, next) {
var self = this;
User.find({where: {email: value}})
.then(function (user) {
// reject if a different user wants to use the same email
if (user && self.id !== user.id) {
return next('Email already in use!');
}
return next();
})
.catch(function (err) {
return next(err);
});
}
}
},
other_field: Sequelize.STRING
});
module.exports = User;
const { DataTypes } = require('sequelize');
const sequelize = require('../config/db');
const UserModel = sequelize.define('user', {
id: {
type: DataTypes.INTEGER(11).UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
validate: {
isUnique: (value, next) => {
UserModel.findAll({
where: { email: value },
attributes: ['id'],
})
.then((user) => {
if (user.length != 0)
next(new Error('Email address already in use!'));
next();
})
.catch((onError) => console.log(onError));
},
},
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
createdAt: {
type: DataTypes.DATE,
allowNull: false,
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false,
},
});
module.exports = UserModel;
然后,在控制器中捕获任何验证错误:
var Sequelize = require('sequelize'),
_ = require('lodash'),
User = require('./path/to/User.model');
exports.create = function (req, res) {
var allowedKeys = ['email', 'other_field'];
var attributes = _.pick(req.body, allowedKeys);
User.create(attributes)
.then(function (user) {
res.json(user);
})
.catch(Sequelize.ValidationError, function (err) {
// respond with validation errors
return res.status(422).send(err.errors);
})
.catch(function (err) {
// every other error
return res.status(400).send({
message: err.message
});
});
您可以验证电子邮件是否已经存在,如下所示:
email: {
type: Sequelize.STRING,
allowNull: false,
validate: {
isEmail:true
},
unique: {
args: true,
msg: 'Email address already in use!'
}
}
使用自定义验证器定义用户模型:
var User = sequelize.define('User',
{
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
isUnique: function (value, next) {
var self = this;
User.find({where: {email: value}})
.then(function (user) {
// reject if a different user wants to use the same email
if (user && self.id !== user.id) {
return next('Email already in use!');
}
return next();
})
.catch(function (err) {
return next(err);
});
}
}
},
other_field: Sequelize.STRING
});
module.exports = User;
const { DataTypes } = require('sequelize');
const sequelize = require('../config/db');
const UserModel = sequelize.define('user', {
id: {
type: DataTypes.INTEGER(11).UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
validate: {
isUnique: (value, next) => {
UserModel.findAll({
where: { email: value },
attributes: ['id'],
})
.then((user) => {
if (user.length != 0)
next(new Error('Email address already in use!'));
next();
})
.catch((onError) => console.log(onError));
},
},
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
createdAt: {
type: DataTypes.DATE,
allowNull: false,
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false,
},
});
module.exports = UserModel;
好吧,这行不通,你可以试着简单地运行
.find()
,然后在回调中操纵查询结果并调用响应。渲染或其他任何东西来向用户发送消息。真的!?我试图编程到Sequelize接口,而不是一个可靠的实现。为什么上述方法不起作用?我只能想象.find在某个地方捕捉到了错误?只是为了澄清一下,User.find({where:{email:email}}).success()工作得非常好(如Sequelize文档中指定的)。问题是Sequelize没有捕捉到错误,或者在其他地方捕捉到错误。据我所知,User.find()
返回一个事件,它会在发出事件时抛出一个错误,因此调用是唯一的('example@example.com“
,甚至尝试try..catch
也不行。好的,看来我还有很多工作要做才能让续集成型。它远没有我被引导去相信的那么强大……这!我不明白为什么其他人需要运行用户。在插入之前查找。@BaNz是的,你可以这样做&显然更好,但是如果你的表中有自动递增值,那么如果你的插入查询因唯一冲突而失败,那么你的自动递增id也会增加,是的,这是任何SQL的工作方式。我很困惑,您似乎使用了列email
的unique
属性(即不作为validate
对象的属性)。假设attributes.column.unique
的值可以是String | Boolean
;但您的值是一个对象(不是字符串或布尔值),其值为:`{args:true,msg:''.'}`。如果将该值添加到validate
对象中,则该值与使用unique
的方式类似;但是在email
(aka column)对象上直接有unique
。unique
参数接受对象,如果它有args
作为“字符串”或“布尔”值。msg属性用作验证消息。我已将其更改为已接受的答案。它是在最初的问题出现将近4年后才被回答的,我只是刚刚注意到了它。我很不安的是,在被接受的答案中的代码包含了一条注释,上面写着“这不起作用”。特别是因为代码似乎依赖于可能不起作用的东西。这是因为我只是复制了问题中的代码,并添加了if语句,这样它就会起作用。我删除了误导性的注释谢谢你的回答。我使用上述方法进行查询,但无法捕获控制器上的验证错误。因为我使用的是wait User.create()而不是User.create().then()。我已尝试在try块中嵌套User.create(),并在catch块中捕获错误,但无法在catch块中获取这些验证错误。有什么建议吗?