Skip to content

Commit

Permalink
fix: notify during replace if existing localState never previously ca…
Browse files Browse the repository at this point in the history
…lculated (#9251)

* fix: if array was empty, use add vs replace

* fix: fix via detection instead
  • Loading branch information
runspired authored Mar 11, 2024
1 parent 489497c commit 76c9d0a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ function replaceRelatedRecordsLocal(graph: Graph, op: ReplaceRelatedRecordsOpera
const identifiers = op.value;
const relationship = graph.get(op.record, op.field);
assert(`expected hasMany relationship`, isHasMany(relationship));

// relationships for newly created records begin in the dirty state, so if updated
// before flushed we would fail to notify. This check helps us avoid that.
const isMaybeFirstUpdate =
relationship.remoteState.length === 0 &&
relationship.localState === null &&
relationship.state.hasReceivedData === false;
relationship.state.hasReceivedData = true;
const { additions, removals } = relationship;
const { inverseKey, type } = relationship.definition;
Expand Down Expand Up @@ -151,7 +158,10 @@ function replaceRelatedRecordsLocal(graph: Graph, op: ReplaceRelatedRecordsOpera
relationship.localState = diff.finalState;
relationship.isDirty = wasDirty;

if (!wasDirty /*&& becameDirty // TODO to guard like this we need to detect reorder when diffing local */) {
if (
isMaybeFirstUpdate ||
!wasDirty /*&& becameDirty // TODO to guard like this we need to detect reorder when diffing local */
) {
notifyChange(graph, op.record, op.field);
}
}
Expand Down
44 changes: 28 additions & 16 deletions tests/main/tests/integration/references/has-many-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,30 @@ import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in

import createTrackingContext from '../../helpers/create-tracking-context';

module('integration/references/has-many', function (hooks) {
setupRenderingTest(hooks);
class Family extends Model {
@hasMany('person', { async: true, inverse: 'family' }) persons;
}

hooks.beforeEach(function () {
const Family = Model.extend({
persons: hasMany('person', { async: true, inverse: 'family' }),
});
class Person extends Model {
@attr name;
@belongsTo('family', { async: true, inverse: 'persons' }) family;
@hasMany('pet', { async: true, inverse: null }) pets;
}

const Person = Model.extend({
name: attr(),
family: belongsTo('family', { async: true, inverse: 'persons' }),
pets: hasMany('pet', { async: true, inverse: null }),
});
class Pet extends Model {
@attr name;
}

const Pet = Model.extend({
name: attr(),
});
module('integration/references/has-many', function (hooks) {
setupRenderingTest(hooks);

hooks.beforeEach(function () {
this.owner.register('model:family', Family);
this.owner.register('model:person', Person);
this.owner.register('model:pet', Pet);

this.owner.register('adapter:application', Adapter.extend());
this.owner.register('serializer:application', class extends JSONAPISerializer {});
this.owner.register('adapter:application', Adapter);
this.owner.register('serializer:application', JSONAPISerializer);
});

testInDebug("record#hasMany asserts when specified relationship doesn't exist", function (assert) {
Expand Down Expand Up @@ -93,6 +93,18 @@ module('integration/references/has-many', function (hooks) {
assert.deepEqual(personsReference.ids(), ['1', '2']);
});

test('ref.ids() updates when using createRecord', async function (assert) {
const store = this.owner.lookup('service:store');

const family = store.createRecord('family');
const person1 = store.createRecord('person', {});
assert.strictEqual(family.hasMany('persons').ids().length, 0);

family.persons = [person1];

assert.strictEqual(family.hasMany('persons').ids().length, 1);
});

test('record#hasMany for linked references', function (assert) {
const store = this.owner.lookup('service:store');

Expand Down

0 comments on commit 76c9d0a

Please sign in to comment.