Skip to content

Commit

Permalink
Serialize top-level polymorphic collections
Browse files Browse the repository at this point in the history
  • Loading branch information
samselikoff committed Jul 30, 2018
1 parent ed00eb2 commit 615df90
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 34 deletions.
6 changes: 4 additions & 2 deletions addon/serializer-registry.js
@@ -1,5 +1,6 @@
import Model from 'ember-cli-mirage/orm/model';
import Collection from 'ember-cli-mirage/orm/collection';
import PolymorphicCollection from 'ember-cli-mirage/orm/polymorphic-collection';
import Serializer from 'ember-cli-mirage/serializer';
import JsonApiSerializer from 'ember-cli-mirage/serializers/json-api-serializer';
import { pluralize, camelize } from './utils/inflector';
Expand All @@ -25,6 +26,7 @@ export default class SerializerRegistry {
let serializer = this.serializerFor(response.modelName);

return serializer.serialize(response, request);

} else if (Array.isArray(response) && response.filter(this._isCollection).length) {
return response.reduce((json, collection) => {
let serializer = this.serializerFor(collection.modelName);
Expand All @@ -44,7 +46,7 @@ export default class SerializerRegistry {
}

serializerFor(type, { explicit = false } = {}) {
let SerializerForResponse = this._serializerMap && (this._serializerMap[camelize(type)]);
let SerializerForResponse = type && this._serializerMap && (this._serializerMap[camelize(type)]);

if (explicit) {
assert(!!SerializerForResponse, `You passed in ${type} as an explicit serializer type but that serializer doesn't exist. Try running \`ember g mirage-serializer ${type}\`.`);
Expand All @@ -68,7 +70,7 @@ export default class SerializerRegistry {
}

_isCollection(object) {
return object instanceof Collection;
return object instanceof Collection || object instanceof PolymorphicCollection;
}

_isModelOrCollection(object) {
Expand Down
7 changes: 6 additions & 1 deletion addon/serializer.js
Expand Up @@ -3,7 +3,7 @@ import Collection from './orm/collection';
import PolymorphicCollection from './orm/polymorphic-collection';
import extend from './utils/extend';
import { singularize, pluralize, camelize } from './utils/inflector';

import assert from './assert';
import _isFunction from 'lodash/isFunction';
import _isArray from 'lodash/isArray';
import _isEmpty from 'lodash/isEmpty';
Expand Down Expand Up @@ -72,6 +72,11 @@ class Serializer {
let hashWithRoot;

if (this.root) {
assert(
!(resource instanceof PolymorphicCollection),
`The base Serializer class cannot serialize a top-level PolymorphicCollection when root is true, since PolymorphicCollections have no type.`
);

let serializer = this.serializerFor(resource.modelName);
let rootKey = serializer.keyForResource(resource);
hashWithRoot = { [rootKey]: hash };
Expand Down
@@ -0,0 +1,67 @@
import { module, test } from 'qunit';
import { Model, hasMany, Serializer } from 'ember-cli-mirage';
import Server from 'ember-cli-mirage/server';

module('Integration | Serializers | Base | Associations | Polymorphic | Top level', function(hooks) {

hooks.beforeEach(function() {
this.server = new Server({
models: {
user: Model.extend({
things: hasMany({ polymorphic: true })
}),
picture: Model.extend(),
car: Model.extend()
}
});
this.user = this.server.create('user', {
things: [
this.server.create('picture', { title: 'Picture 1'}),
this.server.create('car', { name: 'Car 1' })
]
});

});

hooks.afterEach(function() {
this.server.shutdown();
});

test(`it can serialize a polymorphic collection when root is false`, function(assert) {
this.server.config({
serializers: {
application: Serializer.extend({
root: false,
embed: true
})
}
});
let json = this.server.serializerOrRegistry.serialize(this.user.things);

assert.deepEqual(json, [
{
"id": "1",
"title": "Picture 1"
},
{
"id": "1",
"name": "Car 1"
}
]);
});

test(`it throws if trying to serialize a polymorphic collection when root is true`, function(assert) {
this.server.config({
serializers: {
application: Serializer.extend({
root: true
})
}
});

assert.throws(() => {
this.server.serializerOrRegistry.serialize(this.user.things);
}, /The base Serializer class cannot serialize a top-level PolymorphicCollection when root is true/);
});

});
@@ -1,32 +1,34 @@
import Schema from 'ember-cli-mirage/orm/schema';
import Db from 'ember-cli-mirage/db';
import SerializerRegistry from 'ember-cli-mirage/serializer-registry';
import { Model, belongsTo, hasMany, JSONAPISerializer } from 'ember-cli-mirage';
import { module, test } from 'qunit';
import Server from 'ember-cli-mirage/server';
import { Model, belongsTo, hasMany, JSONAPISerializer } from 'ember-cli-mirage';

module('Integration | Serializers | JSON API Serializer | Associations | Polymorphic', function() {

test('it works for belongs to polymorphic relationships', function(assert) {
let schema = new Schema(new Db(), {
photo: Model.extend(),
video: Model.extend(),
comment: Model.extend({
commentable: belongsTo({ polymorphic: true })
})
let server = new Server({
models: {
photo: Model.extend(),
video: Model.extend(),
comment: Model.extend({
commentable: belongsTo({ polymorphic: true })
})
},
serializers: {
application: JSONAPISerializer,
comment: JSONAPISerializer.extend({
include: ['commentable']
})
}
});

let registry = new SerializerRegistry(this.schema, {
application: JSONAPISerializer,
comment: JSONAPISerializer.extend({
include: ['commentable']
})
});
let schema = server.schema;
let photo = schema.photos.create({ title: 'Foo' });
schema.comments.create({ text: 'Pretty foo!', commentable: photo });

let video = schema.videos.create({ title: 'Bar' });
schema.comments.create({ text: 'Love the bar!', commentable: video });

let result = registry.serialize(schema.comments.all());
let result = server.serializerOrRegistry.serialize(schema.comments.all());
assert.deepEqual(result, {
data: [
{
Expand Down Expand Up @@ -71,32 +73,36 @@ module('Integration | Serializers | JSON API Serializer | Associations | Polymor
}
]
});

server.shutdown();
});

test('it works for has many polymorphic relationships', function(assert) {
let schema = new Schema(new Db(), {
user: Model.extend({
things: hasMany({ polymorphic: true })
}),
car: Model.extend(),
watch: Model.extend()
});

let registry = new SerializerRegistry(this.schema, {
application: JSONAPISerializer,
user: JSONAPISerializer.extend({
include: ['things']
})
let server = new Server({
models: {
user: Model.extend({
things: hasMany({ polymorphic: true })
}),
car: Model.extend(),
watch: Model.extend()
},
serializers: {
application: JSONAPISerializer,
user: JSONAPISerializer.extend({
include: ['things']
})
}
});

let schema = server.schema;
let car = schema.cars.create({ make: 'Infiniti' });
let watch = schema.watches.create({ make: 'Citizen' });
let user = schema.users.create({
name: 'Sam',
things: [ car, watch ]
});

let json = registry.serialize(user);
let json = server.serializerOrRegistry.serialize(user);

assert.deepEqual(json, {
data: {
Expand Down Expand Up @@ -131,5 +137,56 @@ module('Integration | Serializers | JSON API Serializer | Associations | Polymor
}
]
});

server.shutdown();
});

test('it works for a top-level polymorphic collection', function(assert) {
let server = new Server({
models: {
user: Model.extend({
things: hasMany({ polymorphic: true })
}),
car: Model.extend(),
watch: Model.extend()
},
serializers: {
application: JSONAPISerializer,
user: JSONAPISerializer.extend({
include: ['things']
})
}
});

let schema = server.schema;
let car = schema.cars.create({ make: 'Infiniti' });
let watch = schema.watches.create({ make: 'Citizen' });
let user = schema.users.create({
name: 'Sam',
things: [ car, watch ]
});

let json = server.serializerOrRegistry.serialize(user.things);

assert.deepEqual(json, {
data: [
{
attributes: {
make: "Infiniti"
},
id: "1",
type: "cars"
},
{
attributes: {
make: "Citizen"
},
id: "1",
type: "watches"
}
]
});

server.shutdown();
});
});

0 comments on commit 615df90

Please sign in to comment.