我如何处理帆中独特的领域?
我已经在我的模型中定义了一个独特的字段,但是当我试图testing它似乎不被Error (E_UNKNOWN) :: Encountered an unexpected error: MongoError: E11000 duplicate key error index:
检查,因为我得到一个Error (E_UNKNOWN) :: Encountered an unexpected error: MongoError: E11000 duplicate key error index:
而不是validation错误。
处理风帆独特领域的最佳方法是什么?
// 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
在此先感谢家伙。
目前unique
属性只在MongoDB中创build一个唯一的索引 。
您可以使用beforeValidate()
callback来检查具有该属性的现有logging,并将结果保存在类variables中。
这种方法确保您的模型返回一个适当的validation错误,可以由客户端进行评估。
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所指出的那样,我之前的解决scheme中有一个错误,它使默认的uniqueEmail
值无用,因为它是在模型声明本身中定义的,因此无法在模型代码中引用。 我相应地编辑了我的答案,谢谢。
将电子邮件定义为唯一字段后,您正尝试使用相同的电子邮件地址创build两个用户。
也许你可以通过该电子邮件地址查询用户 – 如果它已经存在 – 返回一个错误或更新该用户。
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和MongoDB:重复键错误索引
Sails.js文档中的独特模型属性也有一个有趣的地方https://github.com/balderdashy/waterline#indexing
编辑:从http://sailsjs.org/#!documentation/models拉
可用的validation是:
空,必填,notEmpty,undefined,string,alpha,数字,字母数字,电子邮件,url,urlish,ip,ipv4,ipv6,creditcard,uuid,uuidv3,uuidv4,int,整数,如果不是,max,min,minLength,NULL,NULL,布尔值,数组,hex,hexColor,小写,大写,最长长度
@tvollstaedt和David的解决scheme发布了工作,但是这个代码存在很大的问题。 我一整天都在苦苦挣扎,所以我正在修改这个稍微修改过的答案。 我只想评论,但我还没有点。 如果他们可以更新他们,我会很乐意删除这个答案,但是我真的很想帮助那些遇到同样问题的人。
上面的代码使用自定义validation器的问题是,您无法像以前的解决scheme那样从属性中访问属性“uniqueEmail”。 在这些解决scheme中工作的唯一原因是因为他们无意中将“uniqueEmail”投入全球空间。
以下是不使用全局空间的tvollstaedt代码的轻微修改。 它定义了modual.exports外部的uniqueEmail,因此仅限于该模块,但可在整个模块中访问。
可能还有一个更好的解决scheme,但这是最好的,我可以拿出最小的改变,否则优雅的解决scheme。
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(); }); } };
@tvollstaedt你的反应就像一个魅力,顺便说一句,是迄今为止在sailsjs中处理“唯一性”的最优雅的方式。
谢谢!
这是我的两个美分,使用“sails-validation-messages”添加自定义validation消息:
module.exports = { /* Custom validation types */ uniqueEmail: false, types: { uniqueEmail: function(value) { return uniqueEmail; } }, attributes: { firstname:{ type: 'string', required: true, }, lastname:{ type: 'string', required: true, }, email:{ type: 'email', required: true, unique: true, maxLength:50, uniqueEmail:true }, status:{ type: 'string' } }, beforeValidate: function(values, cb) { Application.findOne({email: values.email}).exec(function (err, record) { console.log('before validation ' + !err && !record); uniqueEmail = !err && !record; cb(); }); }, validationMessages: { firstname: { required : 'First name is required', }, lastname: { required : 'Last name is required', }, email: { required : 'Email is required', email : 'Enter valid email', uniqueEmail: 'Email already registered' }, } };
正确的方法来做到这一点!
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(); }); }
};
通过这种方式,我们并没有打破validation者的概念!