What I need is to return a specific "parent" value from a Schema method:
I have two Schemas:
var IP_Set = new Schema({
name: String
});
and
var Hash_IP = new Schema({
_ipset : {
type: ObjectId,
ref: 'IP_Set'
},
description : String
});
In the Hash_IP
schema I would like to have the following method:
Hash_IP.methods.get_parent_name = function get_parent_name() {
return "parent_name";
};
so when I run:
var hash_ip = new Hash_IP(i);
console.log(hash_ip.get_parent_name())
I can get the IP_Set
name value of the associated Hash_IP
instance.
So far I have the following definition, but I can't manage to return the name:
Hash_IP.methods.get_parent_name = function get_parent_name() {
this.model('Hash_IP').findOne({ _ipset: this._ipset })
.populate('_ipset', ['name'])
.exec(function (error, doc) {
console.log(doc._ipset.name);
});
};
I've tried:
Hash_IP.methods.get_parent_name = function get_parent_name() {
this.model('Hash_IP').findOne({ _ipset: this._ipset })
.populate('_ipset', ['name'])
.exec(function (error, doc) {
return doc._ipset.name;
});
};
without results.
Thanks in advance for the help.
I believe that you're very close. Your question isn't very clear on this, but I assume that
.populate('_ipset', ['name'])
.exec(function (error, doc) {
console.log(doc._ipset.name);
});
is working and
.populate('_ipset', ['name'])
.exec(function (error, doc) {
return doc._ipset.name;
});
is not?
Unfortunately the async return
is not working the way you want it to.
.exec
calls your callback function, which returns the name. This does not return the name as the return value for get_parent_name()
, though. That would be nice. (Imagine the return return name
syntax.)
Pass in a callback into get_parent_name()
like this:
Hash_IP.methods.get_parent_name = function get_parent_name(callback) {
this.model('Hash_IP').findOne({ _ipset: this._ipset })
.populate('_ipset', ['name'])
.exec(callback);
};
You can now use instance_of_hash_ip.get_parent_name(function (err, doc) { ... do something with the doc._ipset.name ... });
in your code.
If you use your parent's name a lot, you might want to always return it with your initial query. If you put the .populate(_ipset, ['name'])
into your query for the instance of Hash_IP, then you won't have to deal with two layers of callbacks in your code.
Simply put the find()
or findOne()
, followed by populate()
into a nice static method of your model.
var Hash_IP = new Schema({
_ipset : {
type: ObjectId,
ref: 'IP_Set'
},
description : String
});
Hash_IP.statics.findByDescWithIPSetName = function (desc, callback) {
return this.where('description', new RegExp(desc, 'i'))
.populate('_ipset', ['name']) //Magic built in
.exec(cb)
};
module.exports = HashIpModel = mongoose.model('HashIp', Hash_IP);
// Now you can use this static method anywhere to find a model
// and have the name populated already:
HashIp = mongoose.model('HashIp'); //or require the model you've exported above
HashIp.findByDescWithIPSetName('some keyword', function(err, models) {
res.locals.hashIps = models; //models is an array, available in your templates
});
Each model instance now has models._ipset.name already defined. Enjoy :)