Skip to content

Commit

Permalink
Don't serialize new has many relationships
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanto committed Jan 12, 2018
1 parent b329a2c commit 111c0d6
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 26 deletions.
56 changes: 30 additions & 26 deletions addon/serializers/json-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -602,44 +602,48 @@ const JSONAPISerializer = JSONSerializer.extend({
if (this.shouldSerializeHasMany(snapshot, key, relationship)) {
let hasMany = snapshot.hasMany(key);
if (hasMany !== undefined) {
// only serialize has many relationships that are not new
let nonNewHasMany = hasMany.filter(item => item.record && !item.record.get('isNew'));

json.relationships = json.relationships || {};
if (nonNewHasMany.length > 0) {
json.relationships = json.relationships || {};

let payloadKey = this._getMappedKey(key, snapshot.type);
if (payloadKey === key && this.keyForRelationship) {
payloadKey = this.keyForRelationship(key, 'hasMany', 'serialize');
}
let payloadKey = this._getMappedKey(key, snapshot.type);
if (payloadKey === key && this.keyForRelationship) {
payloadKey = this.keyForRelationship(key, 'hasMany', 'serialize');
}

let data = new Array(hasMany.length);
let data = new Array(nonNewHasMany.length);

for (let i = 0; i < hasMany.length; i++) {
let item = hasMany[i];
for (let i = 0; i < nonNewHasMany.length; i++) {
let item = nonNewHasMany[i];

let payloadType;
let payloadType;

if (isEnabled("ds-payload-type-hooks")) {
payloadType = this.payloadTypeFromModelName(item.modelName);
let deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(item.modelName);
if (isEnabled("ds-payload-type-hooks")) {
payloadType = this.payloadTypeFromModelName(item.modelName);
let deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(item.modelName);

if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) {
deprecate("You used payloadKeyFromModelName to serialize type for belongs-to relationship. Use payloadTypeFromModelName instead.", false, {
id: 'ds.json-api-serializer.deprecated-payload-type-for-has-many',
until: '4.0.0'
});
if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) {
deprecate("You used payloadKeyFromModelName to serialize type for belongs-to relationship. Use payloadTypeFromModelName instead.", false, {
id: 'ds.json-api-serializer.deprecated-payload-type-for-has-many',
until: '4.0.0'
});

payloadType = deprecatedPayloadTypeLookup;
payloadType = deprecatedPayloadTypeLookup;
}
} else {
payloadType = this.payloadKeyFromModelName(item.modelName);
}
} else {
payloadType = this.payloadKeyFromModelName(item.modelName);

data[i] = {
type: payloadType,
id: item.id
};
}

data[i] = {
type: payloadType,
id: item.id
};
json.relationships[payloadKey] = { data };
}

json.relationships[payloadKey] = { data };
}
}
}
Expand Down
141 changes: 141 additions & 0 deletions tests/integration/serializers/json-api-serializer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,147 @@ test('a belongsTo relationship set to a new record will not show in the relation
});
});

test('it should serialize a hasMany relationship', function(assert) {
env.registry.register("serializer:user", DS.JSONAPISerializer.extend({
attrs: {
handles: { serialize: true }
}
}));

run(function() {
serializer.pushPayload(store, {
data: {
type: 'users',
id: 1,
relationships: {
handles: {
data: [
{ type: 'handles', id: 1 },
{ type: 'handles', id: 2 }
]
}
}
},
included: [
{ type: 'handles', id: 1 },
{ type: 'handles', id: 2 }
]
});

let user = store.peekRecord('user', 1);

let serialized = user.serialize({ includeId: true });

assert.deepEqual(serialized, {
data: {
type: 'users',
id: '1',
attributes: {
'first-name': null,
'last-name': null,
title: null
},
relationships: {
handles: {
data: [
{ type: 'handles', id: '1' },
{ type: 'handles', id: '2' }
]
}
}
}
});
});
});

test('it should not include new records when serializing a hasMany relationship', function(assert) {
env.registry.register("serializer:user", DS.JSONAPISerializer.extend({
attrs: {
handles: { serialize: true }
}
}));

run(function() {
serializer.pushPayload(store, {
data: {
type: 'users',
id: 1,
relationships: {
handles: {
data: [
{ type: 'handles', id: 1 },
{ type: 'handles', id: 2 }
]
}
}
},
included: [
{ type: 'handles', id: 1 },
{ type: 'handles', id: 2 }
]
});

let user = store.peekRecord('user', 1);
store.createRecord('handle', { user });

let serialized = user.serialize({ includeId: true });

assert.deepEqual(serialized, {
data: {
type: 'users',
id: '1',
attributes: {
'first-name': null,
'last-name': null,
title: null
},
relationships: {
handles: {
data: [
{ type: 'handles', id: '1' },
{ type: 'handles', id: '2' }
]
}
}
}
});
});
});

test('it should not include any records when serializing a hasMany relationship if they are all new', function(assert) {
env.registry.register("serializer:user", DS.JSONAPISerializer.extend({
attrs: {
handles: { serialize: true }
}
}));

run(function() {
serializer.pushPayload(store, {
data: {
type: 'users',
id: 1
}
});

let user = store.peekRecord('user', 1);
store.createRecord('handle', { user });

let serialized = user.serialize({ includeId: true });

assert.deepEqual(serialized, {
data: {
type: 'users',
id: '1',
attributes: {
'first-name': null,
'last-name': null,
title: null
}
}
});
});
});

testInDebug('JSON warns when combined with EmbeddedRecordsMixin', function(assert) {
assert.expectWarning(function() {
DS.JSONAPISerializer.extend(DS.EmbeddedRecordsMixin).create();
Expand Down

0 comments on commit 111c0d6

Please sign in to comment.