Sails.js中的密码确认和外部模型validation
也许有一天我一直在玩Sails。 我试图围绕在Sails.js中进行大量validation的最佳方式进行讨论。
这是情景:
Registration Form: Username: _______________ E-Mail: _______________ Password: _______________ Confirm: _______________
用户input:
- 一个正确的电子邮件
- 一个已经存在的用户名
- 两个密码不匹配
期望的结果:
Username: _______________ x Already taken E-Mail: _______________ ✓ Password: _______________ ✓ Confirm: _______________ x Does not match
要求,几个要点:
- 用户input的每一个方面都会收到所有的错误信息 (不仅仅是第一个)。 他们不是模糊的 (“用户名已被占用”或“用户名必须至less有4个字母”比“无效的用户名”更好)
- 内置的模型validation显然不会负责检查匹配的密码确认(SRP)
我认为我需要做的是:
UserController的:
create: function(req, res) { try { // use a UserManager-Service to keep the controller nice and thin UserManager.create(req.params.all(), function(user) { res.send(user.toJSON()); }); } catch (e) { res.send(e); } }
的UserManager:
create: function(input, cb) { UserValidator.validate(input); // this can throw a ValidationException which will then be handled by the controller User.create(input, cb); // this line should only be reached if the UserValidator did not throw an exception }
用户:(型号)
attributes: { username: { type: 'string', required: true, minLength: 3, unique: true }, email: { type: 'email', required: true, unique: true }, password: { type: 'string', required: true } }
UserValidator:
这是棘手的部分。 我需要结合input特定的validation(密码确认匹配?)与模型validation(是采取的用户名,是电子邮件地址有效?)。
如果有一种方法来实例化用户模型并执行validation而不保存到Sails / Waterline中的数据库,我认为这将是相当直接的,但似乎没有这种select。
你将如何去解决这个问题? 非常感谢您的帮助!
将会有一些validation,你可以立即在客户端执行,而无需往返服务器。 像比较密码和确认密码,以及validation一个string匹配一个电子邮件正则expression式可以完成与客户端的JavaScript。
对于检查用户名是否存在等其他的事情,你可以使用ajax调用sails来直接询问“这个用户名是否存在”,并根据结果在客户端提供实时validation,或者你可以等待直到用户提交表单并parsing表单提交以显示这些validation。 由于提前检查这样的事情不是100%可靠的(也就是说,在检查之后但在表格被回传之前,有人可以创build一个具有该名字的用户),一些人select放弃预检并且只处理发布后的错误。
Waterline有它自己的内置validation机制,称为Anchor ,它build立在validator.js (以前称为节点validation器)上。 有关可用的validation的完整列表,请参见此处 。 我build议不要定义一个单独的validation层,而是定义一个方法来parsing风帆validation消息,并以一种用户友好和一致的方式对其进行格式化。
如果你想在Waterline为你做什么之外执行自己的validation,你可以在生命周期callback中进行validation,比如beforeCreate(values, callback)
生命周期callback。 如果您检测到错误,则可以将它们作为第一个parameter passing给callback函数,并将其作为错误传递给create collection方法的调用方。
使用生命周期callback的替代方法是创build处理创build的自己的收集方法。 像这样的东西:
Users.validateAndCreate(req.params.all(), function (err, user) { ... });
有关如何创build像这样的集合方法的更多信息可以在我对这个问题的回答中find: 我如何编写sails函数以在Controller中使用?
你可以在你的模型中做到这一点:
module.exports = { types: { mycustomtype: function (password) { return password === this.confirm; } }, attributes: {, password:{ type: 'STRING', required: true, mycustomtype: true } } }