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
filterkey that receives MongoDB findOne filter and finds only one document to change its relationships. - The
relationskey receives an object from the relations of this model. We talk about the relation input here - The
projectionkey is used to receive written data. Also we talk aboutprojectionkey 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 main → user → removeLivedCities:
executing
main → user → removeLivedCities:
after execute
main → user → removeLivedCities:
Add E2E Test
For adding removeLivedCities request to E2E section you should click on the E2E button, like below picture.
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.
The replaced user and cities id is like below picture.
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 main → user → addMostLovedCity:
executing
main → user → addMostLovedCity:
after execute
main → user → addMostLovedCity:
Add E2E Test
Like before, for adding addMostLovedCity request to E2E test section, you should click on the E2E button, like bottom picture.
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.
The replaced user and city id is like below picture.
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 main → user → removeMostLovedCity:
executing
main → user → removeMostLovedCity:
after execute
main → user → removeMostLovedCity:
Add E2E Test
For adding removeMostLovedCity request to E2E section you should click on the E2E button, like below picture.
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.
The replaced user and city id is like below picture.