问题
I'm using sails with mongo db over waterline.
Lets say that I declare 2 models in my sails project like so :
A user model @ models/User.js
simplified:
username: {
type: 'string',
unique: true
},
passports: {
collection: 'Passport',
via: 'owner'
},
aUserFunction: function(){
console.log('I'm a user function');
}
and a passport model @ models/Passport.js
simplified:
password: {
type: 'string'
},
owner: {
model: 'User',
required: true
},
aPassportFunction: function(){
console.log('I'm a passport function');
}
So far so good.
When I fetch one of those associated objects I do it like so:
sails.models.user
.findOne({ username: 'aUsername' })
.populate('passports') // The populate method allows you to get associated data
.exec(function (err, myUser) {
...
JSON.stringify(myUser); //The object returns just fine!
...
}
As expected the returned myUser
object is this:
{
username:"aUsername",
passports:
[
{
password: 'aPass',
owner: 'theUsersId'
}
]
}
I can now run myUser.aUserFunction();
as expected, since myUser
is of type models/User.js
.
If I try to get my hands on the specific passport I can do this:
var passport = myUser.passports[0];
The problem:
Trying to run passport.aPassportFunction();
is impossible, since the returned object is of type Object
and not models/Passport.js
.
Now from what I know theres NO type casting in javascript, and that would be a wonderful time to use it.
I wouldn't like to copy paste the values into a new object in order to use the aPassportFunction()
, it seems like a waste of resources.
Is there any other way to cast this generic passport Object
as models/Passport.js
type.
回答1:
mongodb actually should not store anything besides data, and so it shouldnt store any functions:
Problems storing JS functions in Mongo DB with Node.js
But the reason why myUser.aUserFunction()
works, i believe, is because waterline's findOne actually transforms the object into the waterline object, not what is actually stored in mongodb. Mongodb will only return you a flat file. If you do a mongodb query you will find that your populated association doesn't even exist under the parent object.
So you are limited to what waterline allows you to do.
One suggestion is instead of using the waterline one-to-many association, make a mongodb one-to-many association instead:
myuser.js:
{
username:"aUsername",
passports:
[
ObjectId("passportid"),
ObjectId("passportid")
]
}
Then you will be able to leverage waterline's findOne on the passport object id and get the Passport.js object, instead of a User.js object with only Passport's data embedded.
Details: https://www.safaribooksonline.com/blog/2012/12/18/document-oriented-data-modeling-with-mongodb/
来源:https://stackoverflow.com/questions/30526939/waterline-mongodb-populated-fetched-object-looses-its-type-and-prototype-funct