I am trying to add rows to a table via nested post. my set up is as follows:
Collection type:
Session
session_id
timestamp
relation (Session has many Answers)
Answers
value1 (text)
value2 (text)
I want to create one session with multiple answer objects.
When I make a Post request, it fails as answer objects are not inserted into the table correctly. the body of the post :
I can see session_id, timestamp values appear for Session.
I can also see the id’s appearing in the reference table that is auto generated,
but the nested objects that should create values in Answers objects is not added to the answers table.
The get request returns the following, with an empty list where answers objects should return:
Default logic is create the inner objects, then attach a reference to those inner objects (their unique id’s) in the outer/parent object POST.
However, this means that you would need to make x number of inner object POSTS, get their id’s, temporary store and include them in another outer/parent object POST. So if you had 10 inner objects, you would end up making 10 POST requests + 1 for outer/parent object POST.
I wanted to do this as it was more elegant and you don’t burden the front-end with dictating the request structure. This method exposes only 1 POST request at outer/parent object level and returns the output correctly as 1 object. BUT technically, it still makes 10 inner object POST’s in the backend.
Continuing on with the example in the link above:
'use strict';
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');
// /**
// * Read the documentation (https://strapi.io/documentation/developer-docs/latest/development/backend-customization.html#core-controllers)
// * to customize this controller
// */
module.exports = {
/**
* Create a record.
*
* @return {Object}
*/
async create(ctx) {
let newArticle = ctx.request.body
let entity;
let newTags = [];
// Loop through inner tags if they exist.
if (newArticle.tags.length > 0) {
for (let i = 0; i < newArticle.tags.length; i++) {
// 'tag' refers to model file name, in this case tag.js
// by default, strapi takes the entire object, unless specified ( name: newArticle.tags[I].tag_name)
let newTag = await strapi.query('tag').create(newArticle.tags[i])
newTags.push(newTag.id) // use these id's in parent POST
}
newArticle.tags = newTags // now it has id's from inner objects to push into parent object and reference table in db.
}
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 });
},
};