Skip to content

Instantly share code, notes, and snippets.

@patocallaghan
Last active May 15, 2019 11:15
Show Gist options
  • Save patocallaghan/58e665f6315cb53c06dafdc9c3e7a4fc to your computer and use it in GitHub Desktop.
Save patocallaghan/58e665f6315cb53c06dafdc9c3e7a4fc to your computer and use it in GitHub Desktop.
Ember Model -> Ember Data Transforms
import { setupTest } from 'ember-qunit';
import { setupFactoryGuy } from 'ember-data-factory-guy';
import { module, test } from 'qunit';
import EmberModelBelongsTo from 'embercom/transforms/ember-model-belongs-to';
import { attr } from 'ember-model';
import IntercomModel from 'embercom/models/types/intercom-model';
import sinon from 'sinon';
let FakeModel = IntercomModel.extend({
id: attr(),
name: attr(),
});
module('Team Core | Transform: EmberModelBelongsTo', function(hooks) {
setupTest(hooks);
setupFactoryGuy(hooks);
hooks.beforeEach(function() {
this.transform = EmberModelBelongsTo.create();
});
test('Deserializing an embedded relation creates ember model instance', function(assert) {
let data = { id: 1, name: 'my-fake-model' };
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
assert.equal(deserialized.get('id'), 1);
assert.equal(deserialized.get('name'), 'my-fake-model');
});
test('Deserializing emdedded relation without id adds fake id', function(assert) {
let data = { name: 'my-fake-model' };
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
assert.ok(deserialized.get('id') > 0);
});
test('Deserializing not emdedded relation loads models', function(assert) {
let data = 1;
let opts = { modelClass: FakeModel, embedded: false };
sinon.stub(FakeModel, 'find');
this.transform.deserialize(data, opts);
assert.ok(FakeModel.find.calledWith(1));
FakeModel.find.restore();
});
test('Serializing embedded records', function(assert) {
let data = { id: 1, name: 'my-fake-model' };
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
let serialized = this.transform.serialize(deserialized, opts);
assert.deepEqual(serialized, data);
});
test('Serializing reference records', function(assert) {
let data = 1;
let opts = { modelClass: FakeModel, embedded: false };
let deserialized = this.transform.deserialize(data, opts);
let serialized = this.transform.serialize(deserialized, opts);
assert.deepEqual(serialized, data);
});
test('Deserializing and serializing embedded undefined values', function(assert) {
let data = undefined;
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
let serialized = this.transform.serialize(deserialized, opts);
assert.deepEqual(serialized, data);
});
});
/*
Usage:
BEFORE
export default Model.extend({
tag: belongsTo(Tag, { key: 'tag', embedded: true }),
admin: belongsTo(Admin, { key: 'admin', embedded: false }),
user: belongsTo(User, { key: 'user' }),
});
AFTER
export default DS.Model.extend({
tag: DS.attr('ember-model-belongs-to', { modelClass: Tag, embedded: true }),
admin: DS.attr('ember-model-belongs-to', { modelClass: Admin, embedded: false }),
user: DS.attr('ember-model-belongs-to', { modelClass: User, embedded: false }),
});
*/
import DS from 'ember-data';
import { isEmpty } from '@ember/utils';
let fakePrimaryKey = 0;
export default DS.Transform.extend({
deserialize(serialized, opts) {
if (!serialized) {
return serialized;
}
if (opts.embedded) {
return this._deserializeEmbedded(serialized, opts);
}
return opts.modelClass.find(serialized);
},
_deserializeEmbedded(serialized, opts) {
let modelClass = opts.modelClass;
let primaryKey = modelClass.primaryKey;
if (isEmpty(serialized[primaryKey])) {
serialized[primaryKey] = ++fakePrimaryKey;
}
modelClass.load([serialized]);
return modelClass.find(serialized[primaryKey]);
},
serialize(deserialized, opts) {
if (!deserialized) {
return deserialized;
}
if (opts.embedded) {
return deserialized.toJSON();
}
return deserialized.get('id');
},
});
import { setupTest } from 'ember-qunit';
import { setupFactoryGuy } from 'ember-data-factory-guy';
import { module, test } from 'qunit';
import EmberModelHasMany from 'embercom/transforms/ember-model-has-many';
import { attr } from 'ember-model';
import IntercomModel from 'embercom/models/types/intercom-model';
import sinon from 'sinon';
let FakeModel = IntercomModel.extend({
id: attr(),
name: attr(),
});
module('Team Core | Transform: EmberModelHasMany', function(hooks) {
setupTest(hooks);
setupFactoryGuy(hooks);
hooks.beforeEach(function() {
this.transform = EmberModelHasMany.create();
});
test('Deserializing an embedded relation creates ember model instances', function(assert) {
let data = [{ id: 1, name: 'my-fake-model' }];
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
assert.equal(deserialized.length, 1);
assert.equal(deserialized[0].get('id'), 1);
assert.equal(deserialized[0].get('name'), 'my-fake-model');
});
test('Deserializing emdedded relations without id adds fake id', function(assert) {
let data = [{ name: 'my-fake-model' }];
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
assert.ok(deserialized[0].get('id') > 0);
});
test('Deserializing and serializing emdedded undefined', function(assert) {
let data = undefined;
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
let serialized = this.transform.serialize(deserialized, opts);
assert.deepEqual(serialized, []);
});
test('Deserializing not emdedded relations loads models', function(assert) {
let data = [1, 2];
let opts = { modelClass: FakeModel, embedded: false };
sinon.stub(FakeModel, 'find');
this.transform.deserialize(data, opts);
assert.ok(FakeModel.find.calledWith(1));
assert.ok(FakeModel.find.calledWith(2));
FakeModel.find.restore();
});
test('Serializing an embedded relationship', function(assert) {
let data = [{ id: 1, name: 'my-fake-model' }];
let opts = { modelClass: FakeModel, embedded: true };
let deserialized = this.transform.deserialize(data, opts);
let serialized = this.transform.serialize(deserialized, opts);
assert.deepEqual(serialized, data);
});
test('Serializing a not embedded relationship', function(assert) {
let data = [1];
let opts = { modelClass: FakeModel, embedded: false };
let deserialized = this.transform.deserialize(data, opts);
let serialized = this.transform.serialize(deserialized, opts);
assert.deepEqual(serialized, data);
});
});
/*
Usage:
BEFORE
export default IntercomModel.extend({
availablePermissions: hasMany(Permission, { key: 'available_roles', embedded: true }),
});
AFTER
export default DS.Model.extend({
available_roles: DS.attr('ember-model-has-many', { modelClass: Permission, embedded: true }),
});
*/
import DS from 'ember-data';
import { isEmpty } from '@ember/utils';
let fakePrimaryKey = 0;
export default DS.Transform.extend({
deserialize(serialized, opts = {}) {
if (!serialized) {
return serialized;
}
if (opts.embedded) {
return this._deserializeEmbedded(serialized, opts);
}
return serialized.map(s => opts.modelClass.find(s));
},
_deserializeEmbedded(serialized, opts) {
let primaryKey = opts.modelClass.primaryKey;
serialized.forEach(s => {
if (isEmpty(s[primaryKey])) {
s[primaryKey] = ++fakePrimaryKey;
}
});
return opts.modelClass.loadAndFindModels(serialized);
},
serialize(deserialized = [], opts = {}) {
if (!deserialized) {
return deserialized;
}
let modelClass = opts.modelClass;
let primaryKey = modelClass.primaryKey;
if (!opts.embedded) {
return deserialized.map(d => d.get(primaryKey));
}
return deserialized.map(d => d.toJSON());
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment