The _depopulate() method is failing if the model has a keyId defined to override the default. This is causing other issues such as documents being persisted to the database with the object instead of id reference. E.g. In test test/model-schema-integration.spec.ts, if you change the referenced models to have a different id to the default name of "id", the test 'Ensure document save references instead of populated objects' fails:
test.only('Ensure document save references instead of populated objects', async () => {
// const Card = model('Card', CardSchema); // ORIGINAL,
const Card = model('Card', CardSchema, { idKey: 'cardId' }); // USING DIFFERENT ID,
// const Cat = model('Cat', CatSchema); // ORIGINAL
const Cat = model('Cat', CatSchema, { idKey: 'catId' }); // USING DIFFERENT ID
const UserSchema = new Schema({
isActive: Boolean,
name: String,
card: { type: CardSchema, ref: 'Card' },
cats: [{ type: CatSchema, ref: 'Cat' }],
});
UserSchema.pre('save', (doc) => {
expect(typeof doc.card).toBe('string');
expect(typeof doc.cats[0]).toBe('string');
});
const User = model('User', UserSchema);
await startInTest(getDefaultInstance());
const cardCreated = await Card.create(cardInfo);
const catCreated = await Cat.create({ name: 'Figaro', age: 6 });
const catCreated2 = await Cat.create({ name: 'Garfield', age: 27 });
console.log(`created`, cardCreated, catCreated, catCreated2);
const user = new User(populateDoc);
// user.card = cardCreated.id; // ORIGINAL
user.card = cardCreated.cardId; // USING DIFFERENT ID
// user.cats = [catCreated.id, catCreated2.id]; // ORIGINAL
user.cats = [catCreated.catId, catCreated2.catId]; // USING DIFFERENT ID
const validated = await user._validate();
expect(validated).toBeTruthy();
expect(user._getIdField()).toBe('id');
await user.save();
const result = await User.findById(user.id);
await result._populate();
expect(result.card.cardNumber).toBe(cardInfo.cardNumber);
expect(result.cats[0].name).toBe('Figaro');
await result.save();
expect(typeof result.card).toBe('string');
expect(typeof result.cats[0]).toBe('string');
console.log(`FINAL RESULT IS`, result);
});
Have updated the file src/model/document.ts _depopulate method:
_depopulate(fieldsName: string | string[]) {
let fieldsToPopulate;
if (fieldsName) {
fieldsToPopulate = extractSchemaReferencesFromGivenFields(fieldsName, this.$.schema);
} else {
fieldsToPopulate = extractSchemaReferencesFields(this.$.schema);
}
for (const fieldName in fieldsToPopulate) {
const data = this[fieldName];
if (Array.isArray(data)) {
for (let i = 0; i < data.length; i++) {
const field = data[i];
if (field && field._getId && field._getId()) {
data[i] = field._getId();
}
}
} else if (typeof data === 'object') {
if (data && data._getId && data._getId()) {
this[fieldName] = data._getId();
}
}
}
return this;
}
And tested it for both original 'id' and the 'catId' and 'cardId' and seems to work. . ??
The _depopulate() method is failing if the model has a keyId defined to override the default. This is causing other issues such as documents being persisted to the database with the object instead of id reference. E.g. In test test/model-schema-integration.spec.ts, if you change the referenced models to have a different id to the default name of "id", the test 'Ensure document save references instead of populated objects' fails:
Have updated the file src/model/document.ts _depopulate method:
And tested it for both original 'id' and the 'catId' and 'cardId' and seems to work. . ??