removeRelation function

Update Many to Many Relation

Pay attention to the following code:

const removeLivedCitiesValidator = () => {
  return object({
    set: object({
      _id: objectIdValidation,
      livedCities: array(objectIdValidation),
    }),
    get: coreApp.schemas.selectStruct("user", 1),
  });
};
const removeLivedCities: ActFn = async (body) => {
  const { livedCities, _id } = body.details.set;

  const obIdLivedCities = livedCities.map((lc: string) => new ObjectId(lc));

  return await users.removeRelation({
    filters: { _id: new ObjectId(_id) },
    projection: body.details.get,
    relations: {
      livedCities: {
        _ids: obIdLivedCities,
        relatedRelations: {
          users: true,
        },
      },
    },
  });
};
coreApp.acts.setAct({
  schema: "user",
  actName: "removeLivedCities",
  validator: removeLivedCitiesValidator(),
  fn: removeLivedCities,
});

In the code above, the removeRelation function is used. This function receives an object input with the following keys:

  • A filter key that receives MongoDB findOne filter and finds only one document to change its relationships.
  • The relations key receives an object from the relations of this model. We talk about the relation input here
  • The projection key is used to receive written data. Also we talk about projection key here

In the function above, we remove one or more cities to the set of cities where a user has lived. In fact, in the validation function, the user ID is received along with an array of city IDs, and in the Act function, we convert the array of city IDs into an array of object IDs and give it to the removeRelation function along with the user ID. As a result, on the user side, one or more cities are removed from the livedCities array, and on the city side, this user is removed from each of the cities whose IDs have been sent. (To know the steps to do this and understand how the relatedRelations are managed, please read this section, just note that we do not have a document to add here, and we only do the steps to remove and place the next document in the limited lists.)

Run the code

Since all the code is getting bigger and bigger, we put it on GitHub, you can see and download it here.
By running the codes and going to the playground, you can see and test the functions added to the user.
before execute mainuserremoveLivedCities: Screenshot from 2024-01-08 13-48-53 executing mainuserremoveLivedCities: Screenshot 2024-01-08 at 14-16-37 Lesan Playground after execute mainuserremoveLivedCities: Screenshot from 2024-01-08 14-20-24

Add E2E Test

For adding removeLivedCities request to E2E section you should click on the E2E button, like below picture.

e2e sequence

Then, in the E2E section and removeLivedCities sequence, you should replace the user id and cities id that you set capture in own sequence with default user id and cities id. default user id and cities id in livedCities is like below picture.

e2e sequence

The replaced user and cities id is like below picture.

e2e sequence

Update One to Many Relation

If you have created a single type relationship, and if you set the optional equivalent to false, we can not use removeRelation for that please use the addRelation function to replace it (for example we can not use removeRelation to remove country from a user).
But if you set the optional equal to true, we can use the removeRelation function to erase that relationship along with its relatedrelations.
Let's make an optional one-to-many relationship. We create a new relationship for the user:

  mostLovedCity: {
    optional: true,
    schemaName: "city",
    type: "single",
    relatedRelations: {
      lovedByUser: {
        type: "multiple",
        limit: 3,
        sort: {
          field: "_id",
          order: "desc",
        },
      },
    },
  },

So the full form of users will be:

const users = coreApp.odm.newModel("user", userPure, {
  livedCities: {
    optional: false,
    schemaName: "city",
    type: "multiple",
    sort: {
      field: "_id",
      order: "desc",
    },
    relatedRelations: {
      users: {
        type: "multiple",
        limit: 5,
        sort: {
          field: "_id",
          order: "desc",
        },
      },
    },
  },

  mostLovedCity: {
    optional: true,
    schemaName: "city",
    type: "single",
    relatedRelations: {
      lovedByUser: {
        type: "multiple",
        limit: 5,
        sort: {
          field: "_id",
          order: "desc",
        },
      },
    },
  },

  country: {
    optional: false,
    schemaName: "country",
    type: "single",
    relatedRelations: {
      users: {
        type: "multiple",
        limit: 5,
        sort: {
          field: "_id",
          order: "desc",
        },
      },
    },
  },
});

In this relationship, we add a city as a mostLovedCity for a user, and on the side of the city we add a field called lovedByUser, where we store the last five users who have chosen it as their mostLovedCity.
To erase the mostLovedCity relationship in a user. We must first create this relationship.
So let's write a function to add this relationship:

const addMostLovedCityValidator = () => {
  return object({
    set: object({
      _id: objectIdValidation,
      lovedCity: objectIdValidation,
    }),
    get: coreApp.schemas.selectStruct("user", 1),
  });
};
const addMostLovedCity: ActFn = async (body) => {
  const { lovedCity, _id } = body.details.set;

  return await users.addRelation({
    filters: { _id: new ObjectId(_id) },
    projection: body.details.get,
    relations: {
      mostLovedCity: {
        _ids: new ObjectId(lovedCity),
        relatedRelations: {
          lovedByUser: true,
        },
      },
    },
    replace: true,
  });
};
coreApp.acts.setAct({
  schema: "user",
  actName: "addMostLovedCity",
  validator: addMostLovedCityValidator(),
  fn: addMostLovedCity,
});

In the above function, we get the ID of a user and the ID of a city and store that city as mostLovedCity in the user. Also, on the city side, we add this user to the lovedByUser list.

before execute mainuseraddMostLovedCity: Screenshot from 2024-01-08 14-52-30 executing mainuseraddMostLovedCity: Screenshot 2024-01-08 at 14-53-23 Lesan Playground after execute mainuseraddMostLovedCity: Screenshot from 2024-01-08 14-54-32

Add E2E Test

Like before, for adding addMostLovedCity request to E2E test section, you should click on the E2E button, like bottom picture.

e2e sequence

Then, in the E2E section and addMostLovedCity sequence, you should replace the user id and city id that you set capture in own sequence with default user id and city id. default user id and city id in addMostLovedCity sequence is like below picture.

e2e sequence

The replaced user and city id is like below picture.

e2e sequence

Well, finally, let's write the mostLovedCity remove function:

const removeMostLovedCityValidator = () => {
  return object({
    set: object({
      _id: objectIdValidation,
      lovedCity: objectIdValidation,
    }),
    get: coreApp.schemas.selectStruct("user", 1),
  });
};
const removeMostLovedCity: ActFn = async (body) => {
  const { lovedCity, _id } = body.details.set;

  return await users.removeRelation({
    filters: { _id: new ObjectId(_id) },
    projection: body.details.get,
    relations: {
      mostLovedCity: {
        _ids: new ObjectId(lovedCity),
        relatedRelations: {
          lovedByUser: true,
        },
      },
    },
  });
};
coreApp.acts.setAct({
  schema: "user",
  actName: "removeMostLovedCity",
  validator: removeMostLovedCityValidator(),
  fn: removeMostLovedCity,
});

In the above function, we get the ID of a user along with the ID of a city, and in that user, we delete the mostLovedCity field if it matches this ID, and on the city side, we remove this user from the lovedByUser list. (To know the steps to do this and understand how the relatedRelations are managed, please read this section, just note that we do not have a document to add here, and we only do the steps to remove and place the next document in the limited lists.)

Run the code

Since all the code is getting bigger and bigger, we put it on GitHub, you can see and download it here.
By running the codes and going to the playground, you can see and test the functions added to the user.

before execute mainuserremoveMostLovedCity: Screenshot from 2024-01-08 14-54-32 executing mainuserremoveMostLovedCity: Screenshot 2024-01-08 at 15-27-19 Lesan Playground after execute mainuserremoveMostLovedCity: Screenshot from 2024-01-08 15-54-33

Add E2E Test

For adding removeMostLovedCity request to E2E section you should click on the E2E button, like below picture.

e2e sequence

Then, in the E2E section and removeMostLovedCity sequence, you should replace the user id and city id that you set capture in own sequence with default user id and city id. default user id and city id in removeMostLovedCity sequence is like below picture.

e2e sequence

The replaced user and city id is like below picture.

e2e sequence