Need Help: How to add (if not exists) related records in POST Method

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 :laughing: