Last active
August 29, 2015 14:06
-
-
Save vampolo/8f8237cce2b8a52ab9d4 to your computer and use it in GitHub Desktop.
Ember data embedded record noKeyMixin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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