Node.js 我如何处理帆船的独特领域?
我在模型中定义了一个唯一字段,但当我尝试测试时,它似乎没有被sails检查,因为我得到一个Node.js 我如何处理帆船的独特领域?,node.js,sails.js,waterline,Node.js,Sails.js,Waterline,我在模型中定义了一个唯一字段,但当我尝试测试时,它似乎没有被sails检查,因为我得到一个错误(E_UNKNOWN)::遇到一个意外错误: MongoError:E11000重复键错误索引:改为sails ValidationError 在帆船运动中,处理独特领域的最佳方式是什么 // model/User.js module.exports{ attributes: { email: {required: true, unique: true, type: 'email' }, ...
错误(E_UNKNOWN)::遇到一个意外错误:
MongoError:E11000重复键错误索引:
改为sails ValidationError
在帆船运动中,处理独特领域的最佳方式是什么
// model/User.js
module.exports{
attributes: {
email: {required: true, unique: true, type: 'email' },
....
}
// in my controller
User.create({email: 'hello@gmail.com'}).then(...).fail(....)
User.create({email: 'hello@gmail.com'}).then(...).fail(// throws the mongo error )
// and same goes with update it throws error
提前感谢各位。在将电子邮件定义为唯一字段后,您正在尝试创建两个具有相同电子邮件地址的用户 也许您可以通过该电子邮件地址查询用户-如果它已经存在-返回错误或更新该用户
var params = {email: 'email@email.com'};
User.findOne(params).done(function(error, user) {
// DB error
if (error) {
return res.send(error, 500);
}
// Users exists
if (user && user.length) {
// Return validation error here
return res.send({error: 'User with that email already exists'}, 403.9);
}
// User doesnt exist with that email
User.create(params).done(function(error, user) {
// DB error
if (error) {
return res.send(error, 500);
}
// New user creation was successful
return res.json(user);
});
});
在Sails.js文档中还有一个关于独特模型属性的有趣内容
编辑:
从
可用的验证包括:
空、必填、notEmpty、未定义、字符串、字母、数字、字母数字、电子邮件、url、urlish、ip、ipv4、ipv6、信用卡、uuid、uuidv3、uuidv4、int、整数、数字、有限、十进制、浮点、falsey、truthy、null、notNull、boolean、数组、日期、十六进制、hexColor、小写、大写、后、前、is、regex、notRegex、equals、,包含、不包含、len、in、notIn、max、min、minLength、maxLength当前唯一的
属性
您可以使用beforeValidate()
回调来检查具有该属性的现有记录,并将结果保存在类变量中
这种方法确保您的模型返回一个正确的验证错误,客户端可以对其进行评估
var uniqueEmail = false;
module.exports = {
/**
* Custom validation types
*/
types: {
uniqueEmail: function(value) {
return uniqueEmail;
}
},
/**
* Model attributes
*/
attributes: {
email: {
type: 'email',
required: true,
unique: true, // Creates a unique index in MongoDB
uniqueEmail: true // Makes sure there is no existing record with this email in MongoDB
}
},
/**
* Lifecycle Callbacks
*/
beforeValidate: function(values, cb) {
User.findOne({email: values.email}).exec(function (err, record) {
uniqueEmail = !err && !record;
cb();
});
}
}
编辑
正如thinktt所指出的,我以前的解决方案中存在一个错误,导致默认的uniqueEmail
值无效,因为它是在模型声明本身中定义的,因此不能在模型代码中引用。我已经相应地编辑了我的答案,谢谢。@tvollstaed你的回答很有魅力,顺便说一句,这是迄今为止处理帆船“独特性”的最优雅的方式
谢谢大家!
下面是我使用“sails验证消息”添加自定义验证消息的两分钱:
module.exports={
/*自定义验证类型*/
uniqueEmail:false,
类型:{
uniqueEmail:函数(值){
回信;
}
},
属性:{
名字:{
键入:“字符串”,
要求:正确,
},
姓氏:{
键入:“字符串”,
要求:正确,
},
电邮:{
键入:“电子邮件”,
要求:正确,
独一无二:没错,
最大长度:50,
uniquemail:是的
},
地位:{
键入:“字符串”
}
},
beforeValidate:函数(值,cb){
Application.findOne({email:values.email}).exec(函数(err,record){
log('验证前'+!err&&!记录);
uniqueEmail=!err&&!记录;
cb();
});
},
验证消息:{
名字:{
必填项:“需要名字”,
},
姓氏:{
必填项:“必须输入姓氏”,
},
电邮:{
必需:“需要电子邮件”,
电子邮件:“输入有效电子邮件”,
uniqueEmail:“电子邮件已注册”
},
}
};代码>由@tvollstaedt和David提出的解决方案很有效,但这段代码存在一个大问题。我一整天都在努力解决这个问题,所以我提出了这个稍加修改的答案。我只想评论一下,但我还没有要点。如果他们能更新他们的答案,我会很高兴地删除这个答案,但我真的很想帮助那些和我有同样问题的人
使用自定义验证器的上述代码的问题在于,您无法按照前面两个解决方案尝试的方式从属性中访问属性“uniqueEmail”。它在这些解决方案中起作用的唯一原因是,它们无意中将“UniqueMail”扔进了全球空间
以下是对不使用全局空间的tvollstaedt代码的轻微修改。它在modula.exports之外定义uniqueEmail,因此其范围仅限于模块,但可在整个模块中访问
可能还有更好的解决方案,但这是我能想出的最好的解决方案,只需对其他优雅的解决方案进行最小的更改
var uniqueEmail = false;
module.exports = {
/**
* Custom validation types
*/
types: {
uniqueEmail: function(value) {
return uniqueEmail;
}
},
/**
* Model attributes
*/
attributes: {
email: {
type: 'email',
required: true,
unique: true, // Creates a unique index in MongoDB
uniqueEmail: true // Makes sure there is no existing record with this email in MongoDB
}
},
/**
* Lifecycle Callbacks
*/
beforeValidate: function(values, cb) {
User.findOne({email: values.email}).exec(function (err, record) {
uniqueEmail = !err && !record;
cb();
});
}
};
正确的方法做这件事
module.exports = {
schema: true,
migrate: 'safe',
tableName: 'users',
autoCreatedAt: false,
autoUpdatedAt: false,
adapter: 'mysql',
/**
* Custom validation types
*/
types: {
uniquePhone: function(value) {
return value!=='_unique';
}
},
attributes: {
id: {
type: 'integer',
primaryKey: true,
unique: true,
autoIncrement: true
},
email: {
type: 'email'
},
first_name: {
type: 'string'
},
last_name: {
type: 'string'
},
phone: {
type: 'string',
required: true,
uniquePhone: true
}
},
/**
* Lifecycle Callbacks
*/
beforeValidate: function(values, cb) {
Users.findOne({phone: values.phone}).exec(function(err, record) {
// do whatever you want check against various scenarios
// and so on..
if(record){
values.phone='_unique';
}
cb();
});
}
})
通过这种方式,我们并没有打破验证器的概念 在最新版本的sails v1.2.7中,回调不再有效。如果您遇到一个独特性在您的模型上不起作用的问题—就像我在sails mongo上所做的那样,您需要在控制器中手动配置它
这里有一个例子
//注册
创建:异步(请求、恢复)=>{
const{name,email,password}=req.body;
试一试{
const userExists=wait sails.models.user.findOne({email});
如果(用户存在){
抛出“该电子邮件地址已在使用中”;
}
}
我们能得到一些代码吗?@InternalFX我已经更新了问题,添加了一些代码。Thanks@ginad请将您首选的解决方案标记为正确答案。谢谢,是的,我也在考虑使用此方法,但我只是好奇是否有更好的方法生成ValidationError。我更新了我的帖子,以包含每个用户的验证列表由sailsjs形成。Unique不是其中之一,因此,在尝试创建包含唯一电子邮件的记录时,由您来解释来自mongodb的响应。