-
-
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
[BUGFIX] keep local state after a deletion #5058
Changes from 8 commits
879a814
269b1b4
b972555
4c3d594
e9acc1f
941ca58
9a72fb5
cee07bd
94503e6
4d7f4e8
5830358
e5cdfe4
b538bbf
348b72f
02a5a46
8c3f77d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -728,12 +728,6 @@ export default class InternalModel { | |
} | ||
} | ||
|
||
notifyHasManyRemoved(key, record, idx) { | ||
if (this.hasRecord) { | ||
this._record.notifyHasManyRemoved(key, record, idx); | ||
} | ||
} | ||
|
||
notifyBelongsToChanged(key, record) { | ||
if (this.hasRecord) { | ||
this._record.notifyBelongsToChanged(key, record); | ||
|
@@ -889,13 +883,34 @@ export default class InternalModel { | |
this.eachRelationship((name, relationship) => { | ||
if (this._relationships.has(name)) { | ||
let rel = this._relationships.get(name); | ||
|
||
rel.clear(); | ||
rel.removeInverseRelationships(); | ||
} | ||
}); | ||
Object.keys(this._implicitRelationships).forEach((key) => { | ||
this._implicitRelationships[key].clear(); | ||
this._implicitRelationships[key].removeInverseRelationships(); | ||
let rel = this._implicitRelationships[key]; | ||
|
||
rel.clear(); | ||
rel.removeInverseRelationships(); | ||
}); | ||
} | ||
|
||
/* | ||
@method unloadDeletedRecordFromRelationships | ||
*/ | ||
unloadDeletedRecordFromRelationships() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. per our chat out of band, let's rename this to not conflate this case with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also let's add some comments here as breadcrumbs to our future selves who will clean this up. This does fix an important bug, but currently there are two codepaths whose different semantics are not obvious within the same level of abstraction, ie that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use unload as the term for unloading records, maybe we should call this method something else, like remove? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely. @runspired I guess we missed an instance of the renaming There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. confirm, will rename There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about: internalModel.removeFromInverseRelationships(); The method would now describes concisely what is does not when to use it. The when and why should be provided via docs, or derived contextually from where it is used. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
this.eachRelationship((name) => { | ||
if (this._relationships.has(name)) { | ||
let rel = this._relationships.get(name); | ||
|
||
rel.unloadDeletedInverseInternalModel(this); | ||
} | ||
}); | ||
Object.keys(this._implicitRelationships).forEach((key) => { | ||
let rel = this._implicitRelationships[key]; | ||
|
||
rel.unloadDeletedInverseInternalModel(this); | ||
}); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -671,7 +671,7 @@ const RootState = { | |
isDirty: false, | ||
|
||
setup(internalModel) { | ||
internalModel.clearRelationships(); | ||
internalModel.unloadDeletedRecordFromRelationships(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. internalModel.removeFromInverseRelationships() |
||
}, | ||
|
||
invokeLifecycleCallbacks(internalModel) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,6 +63,25 @@ export default class BelongsToRelationship extends Relationship { | |
this.notifyBelongsToChanged(); | ||
} | ||
|
||
unloadDeletedInverseInternalModelFromOwn(internalModel) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. foo.set(belongsTo, new);
new.destroyRecord();
foo.get(belongsTo) === null;
``
We should not restore canonical when deleting new; we should let belongsto be null. That's consistent with [current behaviour](https://ember-twiddle.com/7f94a0e81ea38d9022a5007ef8be15c8?openFiles=adapters.application.js%2C) and in any case, restoring here is a bit wat |
||
super.unloadDeletedInverseInternalModelFromOwn(internalModel); | ||
let didChange = false; | ||
|
||
if (this.canonicalState === internalModel) { | ||
this.canonicalState = null; | ||
didChange = true; | ||
} | ||
|
||
if (this.inverseInternalModel === internalModel) { | ||
this.inverseInternalModel = this.canonicalState; | ||
didChange = true; | ||
} | ||
|
||
if (didChange === true) { | ||
this.notifyBelongsToChanged(); | ||
} | ||
} | ||
|
||
flushCanonical() { | ||
//temporary fix to not remove newly created records if server returned null. | ||
//TODO remove once we have proper diffing | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,9 @@ | |
import { assert, warn } from '@ember/debug'; | ||
import OrderedSet from '../../ordered-set'; | ||
import _normalizeLink from '../../normalize-link'; | ||
import Ember from 'ember'; | ||
|
||
const { guidFor } = Ember; | ||
|
||
const { | ||
addCanonicalInternalModel, | ||
|
@@ -266,6 +269,33 @@ export default class Relationship { | |
this.flushCanonicalLater(); | ||
} | ||
|
||
unloadDeletedInverseInternalModel(internalModel) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's the case where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per our discussion out of band, let's fix the inconsistency in naming here. |
||
if (!this.inverseKey) { return; } | ||
|
||
// we actually want a union of members and canonicalMembers | ||
// they should be disjoint but currently are not due to a bug | ||
let seen = Object.create(null); | ||
|
||
const unload = inverseInternalModel => { | ||
const id = guidFor(inverseInternalModel); | ||
|
||
if (seen[id] === undefined) { | ||
const relationship = inverseInternalModel._relationships.get(this.inverseKey); | ||
relationship.unloadDeletedInverseInternalModelFromOwn(internalModel); | ||
seen[id] = true; | ||
} | ||
}; | ||
|
||
this.members.forEach(unload); | ||
this.canonicalMembers.forEach(unload); | ||
} | ||
|
||
unloadDeletedInverseInternalModelFromOwn(internalModel) { | ||
this.canonicalMembers.delete(internalModel); | ||
this.members.delete(internalModel); | ||
this.notifyRecordRelationshipRemoved(internalModel); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this method do anything? I only see two implementations and they appear to be noops. https://github.com/emberjs/data/search?utf8=%E2%9C%93&q=notifyRecordRelationshipRemoved& There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this was put here for something with dematerialization that was never completed maybe? |
||
} | ||
|
||
flushCanonical() { | ||
heimdall.increment(flushCanonical); | ||
let list = this.members.list; | ||
|
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.
@hjdivad commenting these out didn't make any tests fail o.O
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.
hmm yeah it looks like the unload tests assert against the id map and the relationship payloads, but not against relationships (either our side or inverse).