我正在尝试检查用户名是否唯一,我认为我需要自定义验证。我编写了以下代码,但它没有返回.validate()
返回的数组中的错误,而是抛出错误,这不是文档中描述的行为,而不是我想要的。< / p>
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
validate: {
isUnique: function (username) {
User.find({ where: { username: username }})
.done(function (err, user) {
if (err) {
throw err;
}
if (user) {
throw new Error('Username already in use');
}
});
}
}
},
答案 0 :(得分:6)
您正在进行的验证是异步的。您调用User.find
方法,然后返回验证方法。 Sequelize无法知道你在验证中做了异步,除非你这么说。一旦你的查找调用完成,你就会抛出错误,但验证已经完成,因此没有代码可以捕获该错误,这意味着抛出了错误并导致应用程序崩溃
告诉sequelize你正在做异步的方法是对你的函数采取第二个参数,这是一个回调。如果您在没有任何参数的情况下调用回调,则验证成功,如果您给它一个参数,则验证失败。
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
validate: {
isUnique: function (username, done) {
User.find({ where: { username: username }})
.done(function (err, user) {
if (err) {
done(err);
}
if (user) {
done(new Error('Username already in use'));
}
done();
});
}
}
},
你能否指出我误导你的文件部分,然后我们可以纠正它:)
答案 1 :(得分:1)
Sequelize支持Promise样式的异步操作。特别是Bluebird.js lib。只需将您的功能更改为专门使用Promise -> next()
模式即可。
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
validate: {
isUnique: function (username) {
User.find({ where: { username: username }})
.then(function (user) {
if (user) {
throw new Error('Username already in use');
}
});
}
}
},
这也将为您处理User.find()
上的任何错误。
See this example in their codebase
当然,处理唯一约束的最简单方法是在字段定义本身上设置unique: true
:
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
unique: true
},
但是这要求你要么使用Sequelize创建表,要么已经有一个具有唯一约束集的表。
答案 2 :(得分:0)
这个问题得到了一个有效的答案,解释了验证选项的工作原理。但在这种情况下,您不必自行检查用户是否存在。
Sequelizejs有一个findOrCreate()方法,可以在做任何事情之前检查是否存在某些事情。
非常有用的方法:)