So this isn’t a perfect example but just a rough one…
What I’m doing is overwriting the create
controller from the model article
which has a manyWay
relation to a model called tag
. The goal here is to allow posting new/existing tags as strings OR the ID of the tag when you are creating a new article.
It will take the array of tags, if it’s an ID (based on SQL, won’t work for mongoose) just add that to the array of IDs. Else if they are strings, it will query the tag model to see if they exist and if not create them. In either case here, it’s adding the ID to the array and overwriting the ctx.request.body.tags
with the new array of IDs.
This isn’t a perfect example and if you are planning to upload media at the same time it will break because it will try to pass strings as IDs, but other than that for normal application/json
POST requests this should work.
Path: ./api/article/controllers/article.settings.json
'use strict';
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');
module.exports = {
/**
* Create a record.
*
* @return {Object}
*/
async create(ctx) {
let newArticle = ctx.request.body
let entity;
let tags = [];
// Loop through tags passed as strings or an existing ID
if (newArticle.tags.length > 0) {
for (let i = 0; i < newArticle.tags.length; i++) {
// Check if tag is an ID or a new one via string
if (typeof(newArticle.tags[i]) === 'number') {
tags.push(newArticle.tags[i])
} else {
// Check if the tag already exists
let check = await strapi.query('tag').find({ name: newArticle.tags[i]})
// If it exists, push that id into an array, else create it and push the new ID
if (check.length > 0 && check[0].name === newArticle.tags[i]) {
tags.push(check[0].id)
} else {
let newTag = await strapi.query('tag').create({ name: newArticle.tags[i]})
tags.push(newTag.id)
}
}
}
// Overwrite the ctx.request.body.tags with the new integer based array
newArticle.tags = tags
}
if (ctx.is('multipart')) {
// need to adjust this for the tags, right now it will break
const { data, files } = parseMultipartData(ctx);
entity = await strapi.services.article.create(data, { files });
} else {
// pass the new request body with the proper array of IDs and create the article
entity = await strapi.services.article.create(newArticle);
}
return sanitizeEntity(entity, { model: strapi.models.article });
},
};
The example may not be perfect, you could probably swap out the for loop with a map, but this was a quick and dirty example. Please feel free to adjust my terrible JS