Skip to content

Commit

Permalink
Pass lid from relationship data to get record data (#7425)
Browse files Browse the repository at this point in the history
The issue appeared in the sideposting scenario:

- model A has belongs to relationship to model B.

- instance of model A and instance of model B are created on the client,

- model A is saved along with model B sent in `include` section of
  payload; the linking is done through `lid`

- server persisted both models and sent the response with
  server-generated `id` along with `lid` sent by the client.

- when belongsTo.updateData() was called while the response payload was
  pushed to the store it couldn't match the record which was already in
  the store with the record data contained in the relationship data
  because `lid` was omitted.

Add a test which ensures that the belongsTo() relationship has correct
status in the sideposting with lid scenario.
  • Loading branch information
azhiv authored Apr 8, 2021
1 parent 2c57905 commit 0ab470c
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ module('Integration | Identifiers - lid reflection', function(hooks) {

class Cake extends Model {
@attr name;
@hasMany('ingredient', { async: false }) ingredients;
@hasMany('ingredient', { inverse: null, async: false }) ingredients;
}

this.owner.register('model:ingredient', Ingredient);
Expand All @@ -165,8 +165,10 @@ module('Integration | Identifiers - lid reflection', function(hooks) {
return payload;
}
}

class TestAdapter extends Adapter {
createRecord(store, ModelClass, snapshot) {
const lid = recordIdentifierFor(snapshot.record.ingredients.firstObject).lid;
return resolve({
data: {
type: 'cake',
Expand All @@ -180,7 +182,7 @@ module('Integration | Identifiers - lid reflection', function(hooks) {
{
type: 'ingredient',
id: '2',
lid: cheeseIdentifier.lid,
lid,
},
],
},
Expand All @@ -190,7 +192,7 @@ module('Integration | Identifiers - lid reflection', function(hooks) {
{
type: 'ingredient',
id: '2',
lid: cheeseIdentifier.lid,
lid,
attributes: {
name: 'Cheese',
},
Expand All @@ -213,11 +215,81 @@ module('Integration | Identifiers - lid reflection', function(hooks) {
const cheese = store.createRecord('ingredient', { name: 'Cheese' });
const cake = store.createRecord('cake', { name: 'Cheesecake', ingredients: [cheese] });

const cheeseIdentifier = recordIdentifierFor(cheese);

await cake.save();

assert.deepEqual(cake.hasMany('ingredients').ids(), ['2']);
assert.equal(cake.ingredients.objectAt(0).name, 'Cheese');
});

test('belongsTo() has correct state after .save() on a newly created record with sideposted child record when lid is provided in the response payload', async function(assert) {
class Topping extends Model {
@attr name;
}

class Cake extends Model {
@attr name;
@belongsTo('topping', { inverse: null, async: false }) topping;
}

this.owner.register('model:topping', Topping);
this.owner.register('model:cake', Cake);

class TestSerializer extends Serializer {
normalizeResponse(_, __, payload) {
return payload;
}
}

class TestAdapter extends Adapter {
createRecord(store, ModelClass, snapshot) {
const lid = recordIdentifierFor(snapshot.record.topping).lid;
return resolve({
data: {
type: 'cake',
id: '1',
attributes: {
name: 'Cheesecake',
},
relationships: {
topping: {
data: {
type: 'topping',
id: '2',
lid,
},
},
},
},
included: [
{
type: 'topping',
id: '2',
lid,
attributes: {
name: 'Cheese',
},
relationships: {
cake: {
data: {
type: 'cake',
id: '1',
},
},
},
},
],
});
}
}
this.owner.register('serializer:application', TestSerializer);
this.owner.register('adapter:application', TestAdapter);

const cheese = store.createRecord('topping', { name: 'Cheese' });
const cake = store.createRecord('cake', { name: 'Cheesecake', topping: cheese });

await cake.save();

assert.deepEqual(cake.belongsTo('topping').id(), '2');
assert.equal(cake.topping.name, 'Cheese');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default class BelongsToRelationship extends Relationship {
);

if (recordData !== null) {
recordData = this.recordData.storeWrapper.recordDataFor(data.type, data.id);
recordData = this.recordData.storeWrapper.recordDataFor(data.type, data.id, data.lid);
}
this.setCanonicalRecordData(recordData);
}
Expand Down

0 comments on commit 0ab470c

Please sign in to comment.