SideLoader module for Ember-RESTless
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
import Ember from 'ember'; | |
var SideLoader = Ember.Object.extend({ | |
}); | |
SideLoader.reopenClass({ | |
loadMany: function(resourceClass) { | |
// GET the items from the 'resourceClass' endpoint | |
return resourceClass.fetch().then(items => { | |
var sideLoad = {}; | |
var mainKey = pluralize(resourceClass.resourceName); | |
// Dig into the depths of Ember-RESTless to find the raw JSON | |
// returned from this request | |
var rawData = items.currentRequest._result; | |
// Create a hash of Ember Objects for each piece of side-loaded | |
// data, using the Ember-RESTless loadMany() API | |
Object.keys(rawData).forEach(key => { | |
if(key !== mainKey) { | |
// Find the model of the side-loaded record | |
var sideClass = RL.client.adapter.serializer | |
.modelFor(singularize(key.dasherize())); | |
sideLoad[key] = sideClass.loadMany(rawData[key]); | |
} | |
}); | |
// For each record (item) in the resourceClass and for each | |
// type of side-loaded record, determine the relationship and | |
// set the relevant side-loaded records onto the main object | |
items.forEach(item => { | |
Object.keys(sideLoad).forEach(sideKey => { | |
// We expect the convention of dependent keys to have the name: | |
// 'attributeId' or 'attributeIds', and 'attribute' would be the | |
// JSON key. | |
var sideRecords = sideLoad[sideKey]; | |
var camelKey = singularize(sideKey).camelize(); | |
var idKey = camelKey + "Ids"; | |
var foreignKey = resourceClass.resourceName.camelize() + "Id"; | |
// Test for "has and belongs to many" or "belongs to": | |
// If the main record contains the ID of one of the side-loaded | |
// records, then it is "has and belongs to many" or "belongs to" | |
if(item.get(idKey)) { | |
item.set(sideKey.camelize(), sideRecords.filter(sideRec => { | |
return item.get(idKey).contains(sideRec.get('id')); | |
})); | |
} | |
// Test for "has many": | |
// If the side-record contains the foreign key, then it is a "has many" | |
else if (sideRecords.get('firstObject').get(foreignKey)) { | |
item.set(sideKey.camelize(), sideRecords.filter(sideRec => { | |
return sideRec.get(foreignKey) === item.get('id'); | |
})); | |
} | |
}); | |
}); | |
return items; | |
}); | |
}, | |
// This is basically the same as loadMany, except this is used | |
// when only 1 item is being fetched. This makes life a little more | |
// simple, since we don't need to iterate through each "main" record, as | |
// there will only be 1. | |
loadSingle: function(resourceClass, id) { | |
return resourceClass.fetch({id:id}).then(item => { | |
var rawData = item.currentRequest._result; | |
var sideLoad = {}; | |
var mainKey = resourceClass.resourceName; | |
Object.keys(rawData).forEach(key => { | |
if(key !== mainKey) { | |
var sideClass = RL.client.adapter.serializer | |
.modelFor(singularize(key.dasherize())); | |
sideLoad[key] = sideClass.loadMany(rawData[key]); | |
} | |
}); | |
Object.keys(sideLoad).forEach(sideKey => { | |
var sideRecords = sideLoad[sideKey]; | |
var camelKey = singularize(sideKey).camelize(); | |
var idKey = camelKey + "Ids"; | |
var foreignKey = resourceClass.resourceName.camelize() + "Id"; | |
// Test for "has and belongs to many" | |
if(item.get(idKey)) { | |
item.set(sideKey.camelize(), sideRecords); | |
} | |
// Test for "has many" | |
else if (sideRecords.get('firstObject').get(foreignKey)){ | |
item.set(sideKey.camelize(), sideRecords); | |
} | |
}); | |
return item; | |
}); | |
} | |
}); | |
export default SideLoader; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment