我正在尝试使用 Express 和 Mongoose 创建一个简单的表单,允许用户将新项目添加到集合中。
猫鼬模式:
var Item = new Schema({
name : {type : String, required : true},
price : {type : Number, required : true},
description : {type: String, required: true},
});
快车路线:
var create = function(req, res) {
Item.create(req.body, function(err) {
if (err) return res.render('admin/items/new', {title: "New Item", errors: _.values(err.errors)});
res.redirect('/admin/items/index');
});
};
到目前为止很简单。我想要做的是添加适当的验证以确保price
用户输入的是数字,如果没有显示适当的错误。
使用上面的代码,如果用户在价格文本字段中输入非数字字符,我会抛出 CastError。
因此,我尝试将以下验证添加到我的架构中:
Item.path('price').validate(function(v, fn) {
if (typeof v === 'number' || v === undefined) return fn(true);
return fn(false);
}, "must-be-numeric");
但是,Mongoose 似乎在应用此验证之前尝试转换该值,因此无法为此返回适当的验证错误,您仍然只会得到一个 CastError。此外, CastError 防止对正在运行的其他字段进行任何验证检查。
我认为我正在尝试做的事情是相当普遍的(在 Rails 中你只需添加validate :price, :numericality => true
到你的模型中就可以了)。
有没有我遗漏的明显模式可以促进这种类型验证?
其他人如何做到这一点?
我尝试过/想到的事情:
- 我意识到在将表单字段传递给 Mongoose 之前,我可以使用辅助验证库(例如 node-validator)来“预验证”表单字段。但是,我真的不希望代码重复,或者将来自两个验证器的错误对象组合在一起以提供一组将反馈给用户的错误的样板混乱。
- 理想情况下,我会使用 HTML5“数字”
input
元素来防止错误的用户输入,但考虑到 Firefox 和 IE 还不支持它,它是一个非首发。