Skip to content

Commit

Permalink
docs(discriminators): add section about changing discriminator key
Browse files Browse the repository at this point in the history
Fix #6087
  • Loading branch information
vkarpov15 committed Jan 2, 2023
1 parent 2aee7c1 commit db81dbb
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 5 deletions.
23 changes: 18 additions & 5 deletions docs/discriminators.md
Expand Up @@ -31,12 +31,25 @@ instances.

### Discriminator keys

The way mongoose tells the difference between the different
discriminator models is by the 'discriminator key', which is
`__t` by default. Mongoose adds a String path called `__t`
to your schemas that it uses to track which discriminator
this document is an instance of.
The way Mongoose tells the difference between the different discriminator models is by the 'discriminator key', which is `__t` by default.
Mongoose adds a String path called `__t` to your schemas that it uses to track which discriminator this document is an instance of.

```javascript
[require:Discriminator keys]
```

### Updating the discriminator key

By default, Mongoose doesn't let you update the discriminator key.
`save()` will throw an error if you attempt to update the discriminator key.
And `findOneAndUpdate()`, `updateOne()`, etc. will strip out discriminator key updates.

```javascript
[require:Update discriminator key]
```

To update a document's discriminator key, use `findOneAndUpdate()` or `updateOne()` with the `overwriteDiscriminatorKey` option set as follows.

```javascript
[require:use overwriteDiscriminatorKey to change discriminator key]
```
36 changes: 36 additions & 0 deletions test/docs/discriminators.test.js
Expand Up @@ -100,6 +100,42 @@ describe('discriminator docs', function() {
assert.equal(event3.__t, 'SignedUp');
});

it('Update discriminator key', async function() {
let event = new ClickedLinkEvent({ time: Date.now(), url: 'google.com' });
await event.save();

event.__t = 'SignedUp';
// ValidationError: ClickedLink validation failed: __t: Cast to String failed for value "SignedUp" (type string) at path "__t"
// acquit:ignore:start
await assert.rejects(async () => {
// acquit:ignore:end
await event.save();
// acquit:ignore:start
}, /__t: Cast to String failed/);
// acquit:ignore:end

event = await ClickedLinkEvent.findByIdAndUpdate(event._id, { __t: 'SignedUp' }, { new: true });
event.__t; // 'ClickedLink', update was a no-op
// acquit:ignore:start
assert.equal(event.__t, 'ClickedLink');
// acquit:ignore:end
});

it('use overwriteDiscriminatorKey to change discriminator key', async function() {
let event = new ClickedLinkEvent({ time: Date.now(), url: 'google.com' });
await event.save();

event = await ClickedLinkEvent.findByIdAndUpdate(
event._id,
{ __t: 'SignedUp' },
{ overwriteDiscriminatorKey: true, new: true }
);
event.__t; // 'SignedUp', updated discriminator key
// acquit:ignore:start
assert.equal(event.__t, 'SignedUp');
// acquit:ignore:end
});

/**
* Discriminator models are special; they attach the discriminator key
* to queries. In other words, `find()`, `count()`, `aggregate()`, etc.
Expand Down

0 comments on commit db81dbb

Please sign in to comment.