Reputation: 5777
My Schemas:
Account: mongoose.model('Account', new Schema({
account_name: String,
company: String,
notes: String,
contact_info: [this.ContactInfo]
})),
ContactInfo: mongoose.model('ContactInfo', new Schema({
name: String,
email: String,
phone: String,
notes: String
}))
When I try to do any actions on contact_info though, it says that the methods don't exist.
var c = new ContactInfo...);
var a = new Account(...);
a.contact_info.create(c); //error, create doesn't exsit
a.contact_info.push(c); //works
a.contact_info.id(...).remove(); //id doesn't exist
Am I doing something wrong?
My full code is here (not too much of it): https://github.com/nycitt/node-survey-builder-api-server/blob/master/accounts.js
I'm receiving input from Backbone.js by the way
Upvotes: 1
Views: 1175
Reputation: 5777
So apparently I did a few things wrong:
In Schemas, reference other Schemas NOT Models:
Good:
var ContactInfoSchema = new Schema({
name: String
});
var AccountSchema = new Schema({
account_name: String,
contact_info: [ContactInfoSchema]
});
var ContactInfo = mongoose.model('ContactInfo', ContactInfoSchema);
var Account = mongoose.model('Account', AccountSchema);
Bad: var ContactInfoSchema = new Schema({ name: String, email: String, phone: String, notes: String });
var AccountSchema = new Schema({
account_name: String,
contact_info: [ContactInfo] //subtle difference
});
var ContactInfo = mongoose.model('ContactInfo', ContactInfoSchema);
var Account = mongoose.model('Account', AccountSchema);
The other thing is doing the following doesn't save anything!!!
account.contact_info.create(params);
account.save();
You also have to do
var c = account.contact_info.create(params);
account.contact_info.push(c);
account.save();
For those interested here are the CRUD methods I created for Account and ContactInfo.
Upvotes: 1
Reputation: 123513
Your issue may be within schemas.js
. When defining an object by literal, this
won't refer to the object being defined:
// ...
contact_info: [this.ContactInfo]
// ...
It'll instead refer to the context surrounding the literal -- in the case of Node modules, the exports
object -- which doesn't have a ContactInfo
property. So, the result is:
// ...
contact_info: [undefined]
// ...
You'll still have an Array
, which is why push
is available. But, Mongoose doesn't know to make it a MongooseDocumentArray
, so it won't have the id
, create
, etc. methods.
You'll have to define your models outside the object to have a reference to them. Also note the change in order:
var ContactInfo = mongoose.model('ContactInfo', new Schema({
// ...
});
var Account = mongoose.model('Account', new Schema({
// ...
contact_info: [ContactInfo]
});
module.exports = {
Account: Account,
ContactInfo: ContactInfo
};
Or, attach them to exports
so this.ContactInfo
is set (same order):
exports.ContactInfo = ...;
exports.Account = ...;
Upvotes: 1