如何添加帮助程序方法来查找和保存猫鼬中的对象。 一个朋友告诉我使用辅助方法,但我一天后无法让它们工作。 我总是收到错误,说findOne()
或save()
不存在,或者下一个回调未定义(当节点编译时......在我执行之前):
我尝试过_schema.方法,_schema.静态...什么都没用...
var email = require('email-addresses'),
mongoose = require('mongoose'),
strings = require('../../utilities/common/strings'),
uuid = require('node-uuid'),
validator = require('validator');
var _schema = new mongoose.Schema({
_id: {
type: String,
trim: true,
lowercase: true,
default: uuid.v4
},
n: { // Name
type: String,
required: true,
trim: true,
lowercase: true,
unique: true,
index: true
}
});
//_schema.index({
// d: 1,
// n: 1
//}, { unique: true });
_schema.pre('save', function (next) {
if (!this.n || strings.isNullOrWhitespace(this.n)){
self.invalidate('n', 'Domain name required but not supplied');
return next(new Error('Domain name required but not supplied'));
}
var a = email.parseOneAddress('test@' + this.n);
if (!a || !a.local || !a.domain){
self.invalidate('n', 'Name is not valid domain name');
return next(new Error('Name is not valid domain name'));
}
next();
});
_schema.statics.validateForSave = function (next) {
if (!this.n || strings.isNullOrWhitespace(this.n)){
return next(new Error('Domain name required but not supplied'));
}
var a = email.parseOneAddress('test@' + this.n);
if (!a || !a.local || !a.domain){
return next(new Error('Name is not valid domain name'));
}
next();
}
_schema.statics.findUnique = function (next) {
this.validateForSave(function(err){
if (err){ return next(err); }
mongoose.model('Domain').findOne({ n: this.n }, next);
//this.findOne({ n: this.n }, next);
});
}
_schema.statics.init = function (next) {
this.findUnique(function(err){
if (err){ return next(err); }
this.save(next);
});
}
var _model = mongoose.model('Domain', _schema);
module.exports = _model;
您因为使用this
而遇到了问题。每次输入一个新函数时this
的上下文都在变化。您可以在 mdn 阅读有关this
的更多信息。
此外,您的回调不允许将任何内容传递到 mongoose 方法中。例如,如果我要创建最基本的"保存"方法,我会执行以下操作:
_schema.statics.basicCreate = function(newDocData, next) {
new _model(newDocData).save(next);
}
现在,如果我想在域集合中搜索唯一文档,我将使用以下方法:
_schema.statics.basicSearch = function(uniqueName, next) {
var query = {n: uniqueName};
_model.findOne(query, function(err, myUniqueDoc) {
if (err) return next(err);
if (!myUniqueDoc) return next(new Error("No Domain with " + uniqueName + " found"));
next(null, myNewDoc);
});
}
猫鼬内置了对你正在做的事情的验证:
_schema.path("n").validate(function(name) {
return name.length;
}, "Domain name is required");
_schema.path("n").validate(function(name) {
var a = email.parseOneAddress("test@" + name);
if (!a || !a.local || !a.domain) {
return false;
}
return true;
}, "Name is not a valid domain name");
它返回一个布尔值。如果为 false,则使用声明的消息将错误传递给.save()
回调。对于验证唯一性:
_schema.path("n").validate(function(name, next) {
var self = this;
this.model("Domain").findOne({n: name}, function(err, domain) {
if (err) return next(err);
if (domain) {
if (self._id === domain._id) {
return next(true);
}
return next(false);
}
return next(true);
});
}, "This domain is already taken");
您在此处使用 self = this
,以便可以访问findOne()
回调中的文档。 如果名称存在并且找到的结果不是文档本身,则false
将传递给回调。
我试过_schema.方法,_schema.statics
澄清一下,.statics
对模型进行操作,.methods
对文档进行操作。Zane 给出了一个很好的静态示例,所以这里有一个方法示例:
_schema.methods.isDotCom = function() {
return (/.com/).test(this.n);
}
var org = new Domain({n: "stuff.org"});
var com = new Domain({n: "things.com"});
org.isDotCom(); // false
com.isDotCom(); // true
观点:让猫鼬做验证是很整洁的,但很容易忘记它正在发生。您可能还希望在应用的一个区域中进行一些验证,同时在其他地方使用不同的验证。我会避免使用其中的大部分,除非你明确知道你每次都必须做同样的事情,而且永远不必这样做。
方法/静态是另一回事。调用isDotCom()
非常方便,而不是每次需要检查时都写出正则表达式测试。它执行单个简单的任务,为您节省一些键入内容并使您的代码更具可读性。使用布尔检查方法可以增加大量的可读性。定义像findByName(Zane的basicSearch
)这样的静态数据是很好的,当你知道你要重复做一个简单的查询时。
将猫鼬视为实用程序,而不是核心功能。