Skip to content

Commit

Permalink
added support for one level depth of inclusion
Browse files Browse the repository at this point in the history
  • Loading branch information
mjtodd committed Mar 6, 2014
1 parent 0413a74 commit 42641c9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 42 deletions.
102 changes: 61 additions & 41 deletions lib/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,13 +490,44 @@ function route(name, model, inflect) {
*/
router.post(individualRoute, methodNotAllowed);

function linkedIds(body, pathstr) {
var path = pathstr.split('.'),
resources = body[path[0]],
ids = [];

function schemaAssociations(schema) {
var associations = [];
_.each(schema, function(value, key) {
var type = _.isArray(value) ? value[0] : value;
type = _.isPlainObject(type) ? type.ref : type;
if(typeof type === 'string') {
type = inflect.pluralize(type);
associations.push({key: key, type: type});
}
});
return associations;
}

function addLinksToBody(body, schema, prefix) {
var baseUrl = this.options.baseUrl
, namespace = this.options.namespace
, associations = schemaAssociations(schema);
if(!associations.length) return;

body.links = body.links || {};
associations.forEach(function(association) {
var name = [prefix, association.key].join('.');
body.links[name] = {
type: association.type
};
if (baseUrl) {
body.links[name].href = baseUrl + '/' + (!!namespace ? namespace + '/' : '') +
association.type + '/{' + name + '}';
}
});
}

function linkedIds(resources, path) {
var ids = [];
_.each(resources, function(resource) {
if (resource.links && resource.links[path[1]]) {
var id = resource.links[path[1]];
if (resource.links && resource.links[path]) {
var id = resource.links[path];
if (_.isArray(id)) {
ids = ids.concat(id);
} else {
Expand All @@ -510,22 +541,26 @@ function route(name, model, inflect) {
function findResources(type, ids) {
var adapter = this.adapter,
model = adapter.model(inflect.singularize(type));

return adapter.findMany(model, ids);
}

function appendLinked(body, req, res) {
function appendLinked(body, resources, schema, inclusions, req, res) {
var promises = [],
_this = this;

_.each(body.links, function(link, path) {
var ids = linkedIds(body, path);
inclusions = _.sortBy(inclusions, function(path) { return path.length; });

_.each(inclusions, function(path) {

var ids = linkedIds(resources, path);
if (ids.length > 0) {
promises.push(findResources.call(_this,link.type,ids).then(function(resources) {
var type = _.isArray(schema[path]) ? schema[path][0] : schema[path];
type = _.isPlainObject(type) ? type.ref : type;
promises.push(findResources.call(_this,type,ids).then(function(resources) {
body.linked = body.linked || {};
body.linked[link.type] = resources;
body.linked[inflect.pluralize(type)] = resources;
return RSVP.all(resources.map(function(resource) {
return afterTransform(inflect.singularize(link.type), resource, req, res);
return afterTransform(inflect.singularize(type), resource, req, res);
}));
}));
}
Expand All @@ -545,40 +580,25 @@ function route(name, model, inflect) {
* @return {Object}
*/
function appendLinks(body, req, res) {
var schemas = this._schema
, baseUrl = this.options.baseUrl
, namespace = this.options.namespace;
var schemas = this._schema,
_this = this;

var promises = [];

_.each(body, function(value, key) {
if(key === 'meta') return;
var modelName = inflect.singularize(key)
, schema = schemas[modelName]
, associations = [];

_.each(schema, function(value, key) {
var type = _.isArray(value) ? value[0] : value;
type = _.isPlainObject(type) ? type.ref : type;
if(typeof type === 'string') {
type = inflect.pluralize(type);
associations.push({key: key, type: type});
}
});

if(!associations.length) return;
body.links = body.links || {};
associations.forEach(function(association) {
var name = [key, association.key].join('.');
body.links[name] = {
type: association.type
};
if (baseUrl) {
body.links[name].href = baseUrl + '/' + (!!namespace ? namespace + '/' : '') +
association.type + '/{' + name + '}';
}
});
, schema = schemas[modelName];
if (schema) {
addLinksToBody.call(_this, body, schema, key);
if (req.query.include)
promises.push(appendLinked.call(_this,body, body[key], schema, req.query.include.split(','), req, res));
}
});

return appendLinked.call(this,body, req, res);
return RSVP.all(promises).then(function() {
return body;
});
}

}
Expand Down
2 changes: 1 addition & 1 deletion test/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ _.each(global.adapters, function(port, adapter) {
})
.then(function() {
request(baseUrl)
.get('/people/' + ids.people[0])
.get('/people/' + ids.people[0] + '?include=pets,soulmate')
.expect('Content-Type', /json/)
.expect(200)
.end(function(error, response) {
Expand Down

0 comments on commit 42641c9

Please sign in to comment.