locks / ember-localstorage-adapter

Name says it all.
MIT License
466 stars 156 forks source link

After a failed .findRecord, it is impossible to create a record with the same id #219

Open arthur5005 opened 7 years ago

arthur5005 commented 7 years ago

Hey, I ran into an issue with ember-data-localstorage today after upgrading to Ember-Data 2.13

The pattern I use with local-storage is usually:

this.store.findRecord('local-model', 'some-id')
  .catch((error) => { 
     ...
        .. if (couldNotBeFound) {
            this.store.createRecord('local-model', { id: 'some-id' })

I get an assertion failure:

The id 'some-id' has already been used with another record for modelClass 'local-model'.

It seems that .findRecord adds the model to the store even if it's not found.

camhux commented 7 years ago

I ran into this too. I believe it's related to this issue with Ember Data 2.13, not this library specifically: https://github.com/emberjs/data/issues/4963

The runloop workaround in that issue thread worked for me to get a "find-or-create" working. Here's what my code looks like, inside a method whose signature returns a promise resolving to a record:

return get(this, 'store').findRecord('model-type', id)
      .catch(() => {
        // `findRecord()` created an internal model for the passed ID.
        // A failed lookup causes that internal model to begin destroying.
        // It's not guaranteed to be destroyed by the time we get here, though.
        // We have to schedule anything that might touch the dematerializing internal
        // model with this ID to happen after dematerialization in the destroy queue.
        return new RSVP.Promise((fulfill) => {
          run.schedule('destroy', () => {
            fulfill(get(this, 'store').createRecord('model-type', { /* attrs */ }));
          });
        });
      });
ldong commented 6 years ago

How about try this,

return get(this, 'store').findRecord('model', id)
  .catch(() => {
     this.store.unloadRecord(this.store.getReference('model', id).internalModel);
  });