hasMany relation CRUD examples using OpWithRelation functions

In Supista ERP, a hasMany relation defines a one-to-many relationship between two components (tables), where a single record in the parent table is associated with multiple records in the child table.

This is the inverse of a belongsTo relation — and in fact, they often exist together as complementary links between two modules.

Example Scenario: A Team has many Members

  • Parent Table: Teams
  • Child Table: Members
  • Supista creates a column in Members: Teams - Members ID
  • Multiple members can be assigned to a single team

createOpWithRelation

Creates a new Member and auto-assigns it to Team ID = 1.

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { createOp } = apiOperations;
  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?.id) {
      resolve({ result: createdData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: 'warning',
          message: 'Could not create data! Please try again later',
        }
      });
    }
  })
}

Example Input

{
  "__d3__newData": {
    "name": "john",
    "email": "john@gmail.com",
    "teams - members ID": 1
  },
  "__d3__parentId": 1,
  "__d3__relationId": "5r1i4x3071"
}

Example Output

{
  "response": {
    "__d3__result": {
      "result": {
        "id": 1,
        "name": "john",
        "email": "john@gmail.com",
        "teams - members ID": 1,
        "__d3__createdBy": 575,
        "__d3__updatedAt": "2025-06-11T10:07:59.065Z",
        "__d3__createdAt": "2025-06-11T10:07:59.065Z",
        "__d3__lastUpdatedBy": null,
        "__d3__deletedAt": null
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

readOpWithRelation

Fetches all members under Team ID = 1.

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { readOpWithRelation } = apiOperations;
  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": "5r1i4x3071"
}

Example Output

{
  "response": {
    "__d3__result": {
      "result": {
        "count": 2,
        "rows": [
          {
            "id": 1,
            "name": "john",
            "email": "john@gmail.com",
            "teams - members ID": 1,
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-11T10:07:59.065Z",
            "__d3__updatedAt": "2025-06-11T10:07:59.065Z",
            "__d3__deletedAt": null
          },
          {
            "id": 2,
            "name": "james",
            "email": "james@gmail.com",
            "teams - members ID": 1,
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-10T13:23:48.594Z",
            "__d3__updatedAt": "2025-06-10T13:23:48.594Z",
            "__d3__deletedAt": null
          }
        ]
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

updateOpWithRelation

Updates Member ID = 1 under Team ID = 1.

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { updateOpWithRelation } = 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": {
    "name": "john Doe",
    "email": "john@gmail.com",
    "teams - members ID": 1,
    "__d3__createdBy": 575,
    "__d3__lastUpdatedBy": null,
    "__d3__createdAt": "2025-06-11T10:07:59.065Z",
    "__d3__updatedAt": "2025-06-11T10:07:59.065Z",
    "__d3__deletedAt": null
  },
  "__d3__id": 1,
  "__d3__parentId": 1,
  "__d3__relationId": "5r1i4x3071"
}

Example Output

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

removeOpWithRelation

Deletes Member ID = 1 only if it belongs to Team ID = 1.

Example Code

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { removeOpWithRelation } = apiOperations;
  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": "5r1i4x3071"
}

Example Output

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

bulkCreateOpWithRelation

Creates multiple new Members and auto-assigns them to Team ID = 1.

Example Code

async function customizeERP(userData, apiOperations) {
  const tableName = "teams";
  const { bulkCreateOpWithRelation } = apiOperations;
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__bulkData: userData?.__d3__bulkData
    }
    const bulkData = await bulkCreateOpWithRelation(
      tableName,
      payload,
      userData.__d3__parentId,
      userData.__d3__relationId
    );
    if (bulkData) {
      resolve({ result: bulkData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not create data! Please try again later"
        }
      });
    }
  })
}

Example Input

{
  "__d3__bulkData": [
    {
      "name": "john",
      "email": "john@gmail.com",
      "teams - members ID": 1
    },
    {
      "name": "james",
      "email": "james@gmail.com",
      "teams - members ID": 1
    }
  ],
  "__d3__parentId": 1,
  "__d3__relationId": "5r1i4x3071"
}

Example Output

{
  "response": {
    "__d3__result": {
      "result": {
        "bulkCreated": 2
      }
    },
    "__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.