I have an Assignment schema
which has references to Groups
and Projects
.
Assignment == Group [One-One Relationship]
Assignment == Projects [One-Many Relationship]
Below is my Asssignment
Schema
var AssignmentSchema = new Schema({
name: String,
group: {
type: Schema.Types.ObjectId,
ref: 'Group'
},
projects: [{type: mongoose.Schema.Types.ObjectId, ref: 'Project'}],
});
If a Group/Project
is removed, how can i update my Assignment Schema.
var ProjectSchema = new Schema({
name: String
});
var GroupSchema = new Schema({
name: String
});
From couple of answers in stackoverflow, i came to know about the remove middleware, but i am not sure how to implement it for one-one and one-many
relationship. Can anyone show me an example of doing it.
ProjectSchema.pre('remove', function(next){
this.model('Assignment').update(
);
});
Relationships:
- A
one-to-one is a relationship
such that a state has only one
capital city and a capital city is the capital of only one state
- A
one-to-many is a relationship
such that a mother has many
children, and the children have only one mother
- A
many-to-many is a relationship
such that a book can be written by
several authors or co-authors, while an author can write several
books.
one-one relationship - If a Project/Group
is removed, how can i update my Assignment
Schema.
Typically you will have one project
mapped to one assignment
and similarly one assignment
mapped to one project
. what you can do here is removing a project and then find the associated project
in assignment model and remove their references.
delete: function(req, res) {
return Project.findById(req.params.id, function(err, project){
return project.remove(function(err){
if(!err) {
Assignment.update({_id: project.assignment}},
{$pull: {projects: project._id}},
function (err, numberAffected) {
console.log(numberAffected);
} else {
console.log(err);
}
});
});
});
}
one-many relationship - If a Project/Group
is removed, how can i update my Assignment
Schema.
In this scenario we are removing a project and then finding all the assignments
which belongs to this project
and removing its reference from them. Here the situation is, there can be many assignments for a single project.
delete: function(req, res) {
return Project.findById(req.params.id, function(err, project){
return project.remove(function(err){
if(!err) {
Assignment.update({_id: {$in: project.assingments}},
{$pull: {project: project._id}},
function (err, numberAffected) {
console.log(numberAffected);
} else {
console.log(err);
}
});
});
});
}
Remove middleware
You could achieve the same thing via middleware
as pointed out by Johnny, just a correction on that..
ProjectSchema.pre('remove', function (next) {
var project = this;
project.model('Assignment').update(
{ projects: {$in: project.assignments}},
{ $pull: { project: project._id } },
{ multi: true },
next
);
});
Typically there can be many projects
belonging to an assignment
and many assignments
belonging to the same project
. You will have an assignment
column in your Project
Schema where one project will relate to multiple assignments.
Note: remove middleware won't work on models and it would only work on your documents. If you are going with remove
middleware ensure in your delete function, you find project
by id first and then on the returned document
apply the remove method, so for the above to work... your delete function would look like this.
delete: function(req, res) {
return Project.findById(req.params.id, function(err, project){
return project.remove(function(err){
if(!err) {
console.log(numberAffected);
}
});
});
}
In the remove
middleware, you're defining the actions to take when a document of the model for that schema is removed via Model#remove
. So:
- When a group is removed, you want to remove the
group
reference to that group's _id
from all assignment docs.
- When a project is removed, you want to remove the
projects
array element references to that project's _id
from all assignment docs.
Which you can implement as:
GroupSchema.pre('remove', function(next) {
var group = this;
group.model('Assignment').update(
{ group: group._id },
{ $unset: { group: 1 } },
{ multi: true },
next);
});
ProjectSchema.pre('remove', function (next) {
var project = this;
project.model('Assignment').update(
{ projects: project._id },
{ $pull: { projects: project._id } },
{ multi: true },
next);
});