Node.js 我如何处理帆船的独特领域?

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' }, ...

我在模型中定义了一个唯一字段,但当我尝试测试时,它似乎没有被sails检查,因为我得到一个
错误(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的响应。