我如何处理帆中独特的领域?

我已经在我的模型中定义了一个独特的字段,但是当我试图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者的概念!