Skip to content

Instantly share code, notes, and snippets.

@mrozema
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrozema/09f41e94a6b232cbd64a to your computer and use it in GitHub Desktop.
Save mrozema/09f41e94a6b232cbd64a to your computer and use it in GitHub Desktop.
SideLoader module for Ember-RESTless
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