-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
WIP client-side-delete semantics unloadRecord
#5273
WIP client-side-delete semantics unloadRecord
#5273
Conversation
61cee15
to
ed208d0
Compare
cc @igorT |
@@ -1488,3 +1488,8 @@ test('many:many async unload', function (assert) { | |||
assert.equal(person1Friends.isDestroyed, true, 'previous ManyArray is destroyed in the runloop after refetching'); | |||
}); | |||
}); | |||
|
|||
test('1 sync : 1 async'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fwiw I do t think QUnit supports this syntax (assuming you are intending to basically create a skip?)...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rwjblue creating a todo, not a skip.
87c8129
to
aa59926
Compare
this.__loadingPromise = null; | ||
} | ||
|
||
_inverseIsAsync() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could live on the parent class
@@ -44,6 +52,10 @@ export default class ManyRelationship extends Relationship { | |||
isPolymorphic: this.isPolymorphic | |||
}); | |||
} | |||
if (this._retainedManyArray !== null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this ever happen if manyArray is not null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets add an assert
} | ||
this._removeInternalModelFromManyArray(this._retainedManyArray, inverseInternalModel); | ||
} else { | ||
this.removeInternalModelFromOwn(inverseInternalModel); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be common for both hasMany and belongsTo?
@@ -143,7 +167,26 @@ export default class ManyRelationship extends Relationship { | |||
return; | |||
} | |||
super.removeInternalModelFromOwn(internalModel, idx); | |||
let manyArray = this.manyArray; | |||
// TODO: explain this madness |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
return this.internalModel.modelName; | ||
_inverseIsAsync() { | ||
// TODO: clean this up; it's for implicit relationships | ||
return this.isAsync; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems incorrect?
let manyArray = this.manyArray; | ||
// TODO: explain this madness | ||
this._removeInternalModelFromManyArray(this.manyArray, internalModel, idx); | ||
this._removeInternalModelFromManyArray(this._retainedManyArray, internalModel, idx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should maybe do this in the async case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we discussed this OOB, but LMK if you still think there's an issue here
@hjdivad I tried this out in our app. We're still stuck in this scenario: import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
unload() {
const clients = this.store.peekAll('client');
// there is one record that matches this, so one record unloaded
clients.filterBy('isCool').forEach((client) => {
client.unloadRecord();
});
// here clients is [Model, Model, null]
// null should not be in the array
// error here because filterBy calls Ember.get on null to try to find hasDirtyAttributes.
clients.filterBy('hasDirtyAttributes').forEach(client => {
client.unloadRecord();
});
}
}
}); It looks like some |
Thanks for the followup @fivetanley. I'll see about reproducing this in a test if you haven't already. |
aa59926
to
ad66b89
Compare
A number of use cases rely on unloadRecord's 2.12 behaviour of treating unloadRecord as a client-side delete on the inverse side of a sync relationship. This pr restores that functionality, while retaining the invalidate+refetch functionality for async relationships. This behaviour is codified in a number of tests within tests/integration/records/unload-test.js Fix #5136, #5137
ad66b89
to
6e8a236
Compare
@igorT this should be good to merge; issues we discussed are handled. |
@fivetanley this doesn't resolve the filter issue you mentioned in your previous comment; that will be addressed in a follow-on issue. |
@fivetanley I wonder if in your use case, calling toArray() after filter would change anything ? |
This isn't tagged with the release channel. Can we please get this in 2.18 LTS? |
Or at least in 3.0 beta ? |
FYI This is included in 3.1.0-beta.1 https://github.com/emberjs/data/releases |
I just released 2.18.1 and 3.0.1 with this pr. Thanks to @sly7-7 for pinging me about including this pr. |
@bmac Thank you!! |
@hjdivad What is the status of the followup on the problem @fivetanley was having? Could somebody explain the reasoning behind the distinction in handling of the canonical state of sync and async relationships for unload? I'm inclined the client side should not be effected by this, as this is more of a server behaviour in my mind. |
Fix #5136, #5137