belongsToMany relation CRUD examples using OpWithRelation functions

In Supista ERP, a belongsToMany relation is used to define a many-to-many relationship between two components, where:

  • One record in Table A can be linked to many records in Table B
  • And one record in Table B can also be linked to many records in Table A

This is made possible using an automatically generated junction table (also called a relation or pivot table), which holds the IDs of both linked records.

Example Scenario: Members ↔ Projects

  • A Member can work on multiple Projects
  • A Project can have multiple Members

In this case:

  • Members and Projects are the two main tables
  • Supista ERP auto-generates a relation table (e.g., Projects - Members Relation) with:
    • Member ID → __d3__id
    • Project ID → __d3__parentId

createOpWithRelation

Adds a new relation row in the junction table, linking Member ↔ Project.

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__newData: { ...userData?.__d3__newData }
    }
    const createdData = await createOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
    if (createdData[0]) {
      resolve({ result: createdData[0] });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: 'warning',
          message: 'Could not read data! Please try again later',
        }
      });
    }
  })
}

Example Input

{
  "__d3__newData": {
    "__d3__id": [2]
  },
  "__d3__parentId": 2,
  "__d3__relationId": "732f6s3717"
}

Example Output

{
  "response": {
    "__d3__result": {
      "result": {
        "projects Id": 2,
        "members Id": 2,
        "__d3__createdAt": "2025-06-18T11:53:37.614Z",
        "__d3__updatedAt": "2025-06-18T11:53:37.614Z",
        "__d3__deletedAt": null
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

readOpWithRelation

Fetches all related records for a parent entity (e.g., all Members in a Project).

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__filterdata: { where: {} }
    }
    const rowsData = await readOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
    if (rowsData?.count) {
      resolve({ result: rowsData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not read data! Please try again later"
        }
      });
    }
  })
}

Example Input

{
  "__d3__filterdata": {
    "where": {}
  },
  "__d3__parentId": 1,
  "__d3__relationId": "732f6s3717"
}

Example Output

{
  "response": {
    "__d3__result": {
      "result": {
        "count": 2,
        "rows": [
          {
            "id": 2,
            "project title": "AI/ML",
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-17T08:59:23.289Z",
            "__d3__updatedAt": "2025-06-17T08:59:23.289Z",
            "__d3__deletedAt": null
          },
          {
            "id": 1,
            "project title": "Web3",
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-16T20:24:46.032Z",
            "__d3__updatedAt": "2025-06-16T20:24:46.032Z",
            "__d3__deletedAt": null
          }
        ]
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

updateOpWithRelation

Updates metadata or related values in the junction row (if any exist).

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
  const { updateOp } = apiOperations;
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__id: userData?.__d3__id,
      __d3__newData: { ...userData?.__d3__newData }
    }
    const updatedData = await updateOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
    if (updatedData?.affectedCount?.[0]) {
      resolve({ result: updatedData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not update data! Please try again later"
        }
      });
    }
  })
}

Example Input

{
  "__d3__newData": {
    "id": 2,
    "project title": "AI/ML/design",
    "__d3__createdBy": 575,
    "__d3__lastUpdatedBy": null,
    "__d3__createdAt": "2025-06-17T08:59:23.289Z",
    "__d3__updatedAt": "2025-06-17T08:59:23.289Z",
    "__d3__deletedAt": null
  },
  "__d3__id": 2,
  "__d3__parentId": 1,
  "__d3__relationId": "732f6s3717"
}

Example Output

{
  "response": {
    "__d3__result": {
      "result": {
        "affectedCount": [1]
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

removeOpWithRelation

Removes the link between a Member and a Project.

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__id: [userData?.__d3__id]
    }
    const deletedData = await removeOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
    if (deletedData?.deletedObjNo) {
      resolve({ result: deletedData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not delete data! Please try again later"
        }
      });
    }
  })
}

Example Input

{
  "__d3__parentId": 1,
  "__d3__id": 2,
  "__d3__relationId": "732f6s3717"
}

Example Output

{
  "response": {
    "__d3__result": {
      "result": {
        "deletedObjNo": 1
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}
Last updated on
Transform Data into Decisions with Supista – Your Intelligent Data Partner
This website uses cookies to improve user experience. By using our website you consent to all cookies in accordance with our Cookie Policy. Learn More.