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

{Backport beta} [BUGFIX beta] Failing test for #5125 and attempted fix #5132

Merged
merged 1 commit into from
Aug 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions addon/-private/system/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,11 @@ Store = Service.extend({
return;
}

let existingInternalModel = this._existingInternalModelForId(modelName, id);

assert(`'${modelName}' was saved to the server, but the response returned the new id '${id}', which has already been used with another record.'`,
isNone(existingInternalModel) || existingInternalModel === internalModel);

this._internalModelsFor(internalModel.modelName).set(id, internalModel);

internalModel.setId(id);
Expand Down Expand Up @@ -2558,27 +2563,31 @@ Store = Service.extend({

assert(`You can no longer pass a modelClass as the first argument to store._buildInternalModel. Pass modelName instead.`, typeof modelName === 'string');

let internalModels = this._internalModelsFor(modelName);
let existingInternalModel = internalModels.get(id);

if (existingInternalModel && existingInternalModel.hasScheduledDestroy()) {
// unloadRecord is async, if one attempts to unload + then sync create,
// we must ensure the unload is complete before starting the create
existingInternalModel.destroySync();
existingInternalModel = null;
}
let existingInternalModel = this._existingInternalModelForId(modelName, id);

assert(`The id ${id} has already been used with another record for modelClass '${modelName}'.`, !existingInternalModel);

// lookupFactory should really return an object that creates
// instances with the injections applied
let internalModel = new InternalModel(modelName, id, this, data);

internalModels.add(internalModel, id);
this._internalModelsFor(modelName).add(internalModel, id);

return internalModel;
},

_existingInternalModelForId(modelName, id) {
let internalModel = this._internalModelsFor(modelName).get(id);

if (internalModel && internalModel.hasScheduledDestroy()) {
// unloadRecord is async, if one attempts to unload + then sync create,
// we must ensure the unload is complete before starting the create
internalModel.destroySync();
internalModel = null;
}
return internalModel;
},

buildInternalModel(modelName, id, data) {
deprecate('buildInternalModel was documented as private and will be removed in the next version of Ember Data.', false, { id: 'ember-data.buildInternalModel', until: '2.17.0' });
return this._buildInternalModel(modelName, id, data);
Expand Down
28 changes: 28 additions & 0 deletions tests/integration/records/unload-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,31 @@ test("after unloading a record, the record can be fetched again soon there after

assert.equal(internalModel.currentState.stateName, 'root.loaded.saved', 'We are loaded after findRecord');
});

test('after unloading a record, the record can be saved again immediately', function (assert) {
assert.expect(0);

const store = env.store;
const data = {
data: {
type: 'person',
id: '1',
attributes: {
name: 'Adam Sunderland'
}
}
};

env.adapter.createRecord = () => Ember.RSVP.Promise.resolve(data);

run(() => {
// add an initial record with id '1' to the store
store.push(data);

// unload the initial record
store.peekRecord('person', '1').unloadRecord();

// create a new record that will again get id '1' from the backend
store.createRecord('person').save();
});
});