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 aboutprojection
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 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.