Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_depopulate does not work if keyId defined for a model #742

Closed
kirstydarragh opened this issue Nov 7, 2023 · 0 comments · Fixed by #744
Closed

_depopulate does not work if keyId defined for a model #742

kirstydarragh opened this issue Nov 7, 2023 · 0 comments · Fixed by #744

Comments

@kirstydarragh
Copy link

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. . ??

gsi-alejandro added a commit that referenced this issue Nov 21, 2023
ejscribner pushed a commit that referenced this issue Jan 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant