Skip to content

Instantly share code, notes, and snippets.

@vampolo
Last active August 29, 2015 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vampolo/8f8237cce2b8a52ab9d4 to your computer and use it in GitHub Desktop.
Save vampolo/8f8237cce2b8a52ab9d4 to your computer and use it in GitHub Desktop.
Ember data embedded record noKeyMixin
var forEach = Ember.EnumerableUtils.forEach;
var get = Ember.get;
function setKey(record, type) {
record.id = Ember.generateGuid(null, type);
record.autoGenerated = true;
}
// chooses a relationship kind to branch which function is used to update payload
// does not change payload if attr is not embedded
function extractEmbeddedRecords(serializer, store, type, partial) {
type.eachRelationship(function(key, relationship) {
if (serializer.hasDeserializeRecordsOption(key)) {
var embeddedType = store.modelFor(relationship.type.typeKey);
if (relationship.kind === "hasMany") {
extractEmbeddedHasMany(store, key, embeddedType, relationship, partial);
}
if (relationship.kind === "belongsTo") {
extractEmbeddedBelongsTo(store, key, embeddedType, relationship, partial);
}
}
});
return partial;
}
// handles embedding for `hasMany` relationship
function extractEmbeddedHasMany(store, key, embeddedType, relationship, hash) {
if (!hash[key]) {
return hash;
}
var ids = [];
var embeddedSerializer = store.serializerFor(embeddedType.typeKey);
var parentSerializer = store.serializerFor(relationship.parentType.typeKey);
var noKeyOnEmbeddedRecord = parentSerializer.hasNoKeyOption(key);
forEach(hash[key], function(data) {
var embeddedRecord = embeddedSerializer.normalize(embeddedType, data, null);
if (noKeyOnEmbeddedRecord && embeddedRecord.id == null) {
setKey(embeddedRecord, embeddedType);
}
store.push(embeddedType, embeddedRecord);
ids.push(embeddedRecord.id);
});
hash[key] = ids;
return hash;
}
function extractEmbeddedBelongsTo(store, key, embeddedType, relationship, hash) {
if (!hash[key]) {
return hash;
}
var embeddedSerializer = store.serializerFor(embeddedType.typeKey);
var parentSerializer = store.serializerFor(relationship.parentType.typeKey);
var noKeyOnEmbeddedRecord = parentSerializer.hasNoKeyOption(key);
var embeddedRecord = embeddedSerializer.normalize(embeddedType, hash[key], null);
if (noKeyOnEmbeddedRecord && embeddedRecord.id == null) {
setKey(embeddedRecord, embeddedType);
}
store.push(embeddedType, embeddedRecord);
hash[key] = embeddedRecord.id;
//TODO Need to add a reference to the parent later so relationship works between both `belongsTo` records
return hash;
}
DS.NoKeyMixin = Ember.Mixin.create({
normalize: function(type, hash, prop) {
//
// got from RESTSerializer
//
if (!hash) { return hash; }
this.normalizeId(hash);
this.normalizeAttributes(type, hash);
this.normalizeRelationships(type, hash);
this.normalizeUsingDeclaredMapping(type, hash);
this.applyTransforms(type, hash);
var normalizedHash = hash;
//var normalizedHash = this._super(type, hash, prop);
return extractEmbeddedRecords(this, this.store, type, normalizedHash);
},
serializeBelongsTo: function(record, json, relationship) {
var attr = relationship.key;
if (this.noSerializeOptionSpecified(attr)) {
this._super(record, json, relationship);
return;
}
var includeIds = this.hasSerializeIdsOption(attr);
var includeRecords = this.hasSerializeRecordsOption(attr);
var embeddedRecord = record.get(attr);
var key, includeId;
if (includeIds) {
key = this.keyForRelationship(attr, relationship.kind);
if (!embeddedRecord) {
json[key] = null;
} else {
json[key] = get(embeddedRecord, 'id');
}
} else if (includeRecords) {
key = this.keyForAttribute(attr);
if (!embeddedRecord) {
json[key] = null;
} else {
includeId = this.hasNoKeyOption(key) === false;
json[key] = embeddedRecord.serialize({includeId: includeId});
this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, json[key]);
}
}
},
serializeHasMany: function(record, json, relationship) {
var attr = relationship.key;
if (this.noSerializeOptionSpecified(attr)) {
this._super(record, json, relationship);
return;
}
var includeIds = this.hasSerializeIdsOption(attr);
var includeRecords = this.hasSerializeRecordsOption(attr);
var key, includeId;
if (includeIds) {
key = this.keyForRelationship(attr, relationship.kind);
json[key] = get(record, attr).mapBy('id');
} else if (includeRecords) {
key = this.keyForAttribute(attr);
json[key] = get(record, attr).map(function(embeddedRecord) {
includeId = this.hasNoKeyOption(key) === false;
var serializedEmbeddedRecord = embeddedRecord.serialize({includeId: includeId});
this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, serializedEmbeddedRecord);
return serializedEmbeddedRecord;
}, this);
}
},
hasNoKeyOption: function(attr) {
var option = this.attrsOption(attr);
return (option && option.noKey === true && option.embedded === 'always');
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment