Data: DS.Model.destroyRecord does not unload record from store

Created on 5 Jun 2017  路  6Comments  路  Source: emberjs/data

Scenario:

const memberA = store.createRecord('member', { name: 'Bob' })
await memberA.save() // server responds with an id of 5678
await memberA.destroyRecord()
const memberB = store.createRecord('member', { name: 'Bob' })
await memberB.save() // server responds with an id of 5678

Expectation:

This should work no problem, memberA and memberB should be different records, that have the same 'name'

Reality:

You cannot update the id index of an InternalModel once set. Attempted to update ${id}.

I believe what's happening is that destroyRecord is not unloading the internalModel, and therefore upon creation throwing this error

On closer inspection, it does seem that store._removeFromIdMap and internalModel.destroy only get called from the unload method

It is unclear from the docs whether destroyRecord also removes internal references

Has PR unload-apis

Most helpful comment

This is still an issue in [email protected]

I just hit exactly the same problem with exactly the same scenario as described in the first post.
I've tried to unload record after deletion

return coupon.destroyRecord().then(() => {
    this.get('store').unloadRecord(coupon);
});

But still got error Error: Assertion Failed: 'coupon' was saved to the server, but the response returned the new id 'XXX', which has already been used with another record.'

All 6 comments

I think this is fixed by #5126, so I am closing.

@kweng2 please reopen if you are still running into this issue after upgrading. Thanks!

This is still an issue in [email protected]

I just hit exactly the same problem with exactly the same scenario as described in the first post.
I've tried to unload record after deletion

return coupon.destroyRecord().then(() => {
    this.get('store').unloadRecord(coupon);
});

But still got error Error: Assertion Failed: 'coupon' was saved to the server, but the response returned the new id 'XXX', which has already been used with another record.'

I checked the unloadRecod() as follows:

unloadRecord()
{
  if (this.isDestroyed) {
    return;
  }
  this._internalModel.unloadRecord();
}

and realised it does not unload destroyed record and therefore I unloaded my record using:

model._internalModel.unloadRecord();

and it worked.

I'm sure this hack is not the good way of doing it, but it works till the right solution is proposed!

This should be re-examined following the landing of #5378

5455 is in-progress to address this; however, semantics and teardown timing issues around getting deleteRecord and deleteRecord.save correct on isNew records has held it up.

Was this page helpful?
0 / 5 - 0 ratings