Handle relationships update

This commit is contained in:
Aurélien Georget 2016-02-08 12:07:58 +01:00
parent 047f68383f
commit 2da3adc1be
4 changed files with 84 additions and 19 deletions

View File

@ -35,7 +35,6 @@ module.exports = {
// HTTP methods allowed
switch (this.default.method) {
case 'GET':
// Nothing to do
try {
yield this.fetchQuery(ctx);
} catch (err) {
@ -44,20 +43,27 @@ module.exports = {
break;
case 'PATCH':
case 'POST':
// TODO:
// - Detect relationships edition or addition
// - Fetch and format body
try {
yield this.fetchSchema(ctx);
yield this.formatBody(ctx);
if (utils.getObject(utils.matchedRoute(ctx)) === 'relationships') {
yield this.fetchRelationRequest(ctx);
yield this.formatRelationBody(ctx);
} else {
yield this.fetchSchema(ctx);
yield this.formatBody(ctx);
}
} catch (err) {
throw err;
}
break;
case 'DELETE':
// TODO:
// - Detect relationships deletion
// - Fetch and format body
if (utils.getObject(utils.matchedRoute(ctx)) === 'relationships') {
try {
yield this.fetchRelationRequest(ctx);
yield this.formatRelationBody(ctx);
} catch (err) {
throw err;
}
}
break;
default:
throw {
@ -69,6 +75,58 @@ module.exports = {
}
},
/**
* Format attributes for relationships request to get more simple API
*/
formatRelationBody: function * (ctx) {
ctx.request.body = _.map(ctx.request.body.data, 'id');
},
/**
* Fetch request for relationships
*/
fetchRelationRequest: function * (ctx) {
const body = ctx.request.body;
if (!body.hasOwnProperty('data')) {
throw {
status: 403,
body: {
message: 'Missing `data` member'
}
};
} else if (_.isPlainObject(body.data) && !utils.isRessourceObject(body.data)) {
throw {
status: 403,
body: {
message: 'Invalid ressource object'
}
};
} else if (_.isArray(body.data)) {
const errors = _.remove(_.map(body.data, function (n, position) {
if (!utils.isRessourceObject(n) || _.isUndefined(utils.getType(ctx, _.get(n, 'type')))) {
return {
position: position,
message: 'Invalid ressource object or unknow type'
};
}
}), function (n) {
return !_.isUndefined(n);
});
if (!_.isEmpty(errors)) {
throw {
status: 403,
body: {
message: errors
}
};
}
}
},
/**
* Format attributes for more simple API
*/

View File

@ -163,7 +163,7 @@ module.exports = {
});
// TODO:
// - Execute some requests to get first, lastest, previous and next record
// - Call request to get first, latest, previous and next record
switch (object) {
default:

View File

@ -10,6 +10,7 @@ const _ = require('lodash');
// Local Strapi dependencies.
const request = require('./helpers/request');
const response = require('./helpers/response');
const utils = require('./utils/utils');
/**
* JSON API hook
@ -24,8 +25,6 @@ module.exports = function (strapi) {
initialize: function (cb) {
function * _interceptor(next) {
const self = this;
// Wait for downstream middleware/handlers to execute to build the response
yield next;
@ -42,15 +41,11 @@ module.exports = function (strapi) {
// Intercept success requests
// Detect route
const matchedRoute = _.find(strapi.router.stack, function (stack) {
if (new RegExp(stack.regexp).test(self.request.url) && _.includes(stack.methods, self.request.method.toUpperCase())) {
return stack;
}
});
const matchedRoute = utils.matchedRoute(this);
if (!_.isUndefined(matchedRoute)) {
// Handlers set the response body
const actionRoute = strapi.config.routes[self.request.method.toUpperCase() + ' ' + matchedRoute.path];
const actionRoute = strapi.config.routes[this.request.method.toUpperCase() + ' ' + matchedRoute.path];
if (!_.isUndefined(actionRoute)) {
response.set(this, matchedRoute, actionRoute);

View File

@ -54,7 +54,7 @@ module.exports = {
getType: function (ctx, supposedType) {
// Relationships or related ressource
if (strapi.models.hasOwnProperty(supposedType.toLowerCase()) && ctx.params.hasOwnProperty('relation')) {
if (strapi.models.hasOwnProperty(supposedType.toLowerCase()) && ctx.params.hasOwnProperty('relation') && ctx.method === 'GET') {
return _.first(_.reject(_.map(strapi.models[supposedType.toLowerCase()].associations, function (relation) {
return (ctx.params.hasOwnProperty('relation') && ctx.params.relation === relation.alias) ? relation.model || relation.collection : undefined;
}), _.isUndefined));
@ -96,6 +96,18 @@ module.exports = {
}
return null;
},
/**
* Find router object for matched route
*/
matchedRoute: function (ctx) {
return _.find(strapi.router.stack, function (stack) {
if (new RegExp(stack.regexp).test(ctx.request.url) && _.includes(stack.methods, ctx.request.method.toUpperCase())) {
return stack;
}
});
}
};