Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #7 from kunai-consulting/fix/remove-nested-relatio…
Browse files Browse the repository at this point in the history
…nship

Remove unloaded objects from nested relationshps
  • Loading branch information
veelenga authored May 18, 2019
2 parents 3d1a92d + 1632e42 commit 20e3e26
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 9 deletions.
12 changes: 8 additions & 4 deletions addon/mixins/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ const resetRelations = function(record) {
Object.keys(record.get('__recordsJustSaved') || {}).forEach((relationName) => {
let relationRecords = record.get('__recordsJustSaved')[relationName];

relationRecords.forEach((r) => {
relationRecords.forEach(({ parent, relatedRecord }) => {
let r = relatedRecord;
let shouldUnload = r.get('isNew') || r.get('markedForDestruction');
let relation = parent.get(relationName);
if (shouldUnload) {
if (isPresent(record.get(relationName))) {
record.get(relationName).removeObject(r);
if (isPresent(relation)) {
relation.removeObject(r);
}
r.unloadRecord();
} else if (r.get('markedForDeletion')) {
record.get(relationName).removeObject(r);
if (isPresent(relation)) {
relation.removeObject(r);
}
r.set('markedForDeletion', false);
}
});
Expand Down
10 changes: 5 additions & 5 deletions addon/mixins/nested-relations.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const addToIncludes = function(payload, includedRecords) {
}
};

const hasManyData = function(relationName, relatedRecords, subRelations, manyToManyDeleted, includedRecords) {
const hasManyData = function(parent, relationName, relatedRecords, subRelations, manyToManyDeleted, includedRecords) {
let payloads = [];
savedRecords[relationName] = [];

Expand All @@ -126,7 +126,7 @@ const hasManyData = function(relationName, relatedRecords, subRelations, manyToM
addToIncludes(payload, includedRecords);

payloads.push(payloadForRelationship(payload));
savedRecords[relationName].push(relatedRecord);
savedRecords[relationName].push({ parent, relatedRecord });
});
return { data: payloads };
};
Expand All @@ -139,11 +139,11 @@ const belongsToData = function(relatedRecord, subRelations, includedRecords) {
return { data: payloadForRelationship(payload) };
};

const processRelationship = function(name, kind, relationData, subRelations, manyToManyDeleted, includedRecords, callback) {
const processRelationship = function(parent, name, kind, relationData, subRelations, manyToManyDeleted, includedRecords, callback) {
let payload = null;

if (kind === 'hasMany') {
payload = hasManyData(name, relationData, subRelations, manyToManyDeleted, includedRecords);
payload = hasManyData(parent, name, relationData, subRelations, manyToManyDeleted, includedRecords);
} else {
payload = belongsToData(relationData, subRelations, includedRecords);
}
Expand All @@ -158,7 +158,7 @@ const processRelationships = function(relationshipHash, jsonData, record, includ
jsonData.relationships = {};

iterateRelations(record, relationshipHash, (name, kind, related, subRelations, manyToManyDeleted) => {
processRelationship(name, kind, related, subRelations, manyToManyDeleted, includedRecords, (payload) => {
processRelationship(record, name, kind, related, subRelations, manyToManyDeleted, includedRecords, (payload) => {
let serializer = record.store.serializerFor(record.constructor.modelName);
let serializedName = serializer.keyForRelationship(name);
jsonData.relationships[serializedName] = payload;
Expand Down
1 change: 1 addition & 0 deletions tests/dummy/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,6 @@ export default function() {

this.get('/authors/:id');
this.get('/tags/:id');
this.get('/descriptions/:id');
this.get('/tags');
}
70 changes: 70 additions & 0 deletions tests/unit/mixins/model-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,76 @@ module('Unit | Mixin | model', function(hooks) {
});
});

test('resetting nested relations', function(assert) {
let store = this.owner.lookup('service:store');
let done = assert.async();
server.patch('/posts/:id', (db, request) => {
let { included } = JSON.parse(request.requestBody);
assert.ok(included.find((obj) => obj.type === 'descriptions'));

done();
let post = db.posts.find(request.params.id);
post.tags.models[0].createDescription({ name: 'Description 2'});
return post;
});

let post = server.create('post');
post.createTag({ name: 'tag1' });
post.createTag({ name: 'tag2' });
let tag = post.tags.models[0];
server.create('description', { tag: tag });

run(() => {
store.pushPayload({
data: {
type: 'posts',
id: 1,
relationships: {
tags: {
data: [
{ type: 'tags', id: '2' },
{ type: 'tags', id: '3' }
]
}
}
},
included: [
{
type: 'tags',
id: '2',
attributes: { name: 'tag1' },
relationships: {
descriptions: {
data: [
{ type: 'descriptions', 'id': '1', method: 'create' }
]
}
}
},
{ type: 'tags', id: '3', attributes: { name: 'tag2' } },
{ type: 'descriptions', 'id': '1', attributes: { name: 'description' } },
]
});
});

let newDescription = store.createRecord('description', { name: 'Description 2'});
post = store.peekRecord('post', 1);
tag = post.tags.firstObject;
tag.descriptions.addObject(newDescription);

let done2 = assert.async();
run(() => {
post.save({ adapterOptions: { relationships: ['tags', { tags: 'descriptions' }] } }).then(async (p) => {
let tags = await p.tags;
let descriptions = await tags.firstObject.descriptions;
assert.equal(descriptions.length, 2);
assert.equal(descriptions.firstObject.id, 1);
assert.equal(descriptions.lastObject.id, 2);
done2();
});
});
});

test('it should correctly save deeply nested has many relations', async function(assert) {
assert.expect(1);

Expand Down

0 comments on commit 20e3e26

Please sign in to comment.