I have two schemas as below.
MirFile Schema
const mongoose = require("mongoose");
const {ObjectId} = mongoose.Schema
// Creating a Schema for uploaded files
const MirFileSchema = new mongoose.Schema({
createdAt: {
type: Date,
default: Date.now,
},
name: {
type: String,
required: [true, "Uploaded file must have a name"],
},
image:{
type:String
},
belongsTo:{
type:ObjectId,
ref:"MirFolder"
}
});
const File = mongoose.model("MirFile", MirFileSchema);
MirFileSchema.pre('remove', function(next) {
MirSubFile.remove({belongsTo: this._id}).exec();
next();
});
module.exports = File;
MirSubFileSchema
const mongoose = require("mongoose");
const {ObjectId} = mongoose.Schema
// Creating a Schema for uploaded subfiles
const MirSubFileSchema = new mongoose.Schema({
createdAt: {
type: Date,
default: Date.now,
},
text: {
type: String,
required: [true, "Uploaded file must have a text"],
},
image:{
type:String
},
belongsTo:{
type:ObjectId,
ref:"MirFile"
}
});
const File = mongoose.model("MirSubFile", MirSubFileSchema);
module.exports = File;
When I delete MirFile the document from MirSubFile which holds the _id of MirFile in belongsTo field must be deleted.I have used prehook but its not working.Any guide.?
Why don't you simply add your own 'deleteOne' or 'remove' Mongoose middleware on the MirFileSchema to deleteOne or remove all other documents
exports.DeleteMirFileSchema = (req, res) => {
MirFileSchema.deleteOne({ _id: req.query._id }, { new: true }, (err, data) => {
if (err) {
console.log(err);
let errorKeyArray = Object.keys(err.errors);
let msgArray = errorKeyArray.map((obj) => {
return err.errors[obj];
});
ResponseObj.errorResponse(res, { status: 400, msg: msgArray.join(", ") });
} else ResponseObj.successResponse(res, data);
});
};
Related
I have a Comment Model, User Model and Post model. In Post Model, there is a field called 'comment' and I referenced Comment model there. That way, every comment made on that post will be populated.
Now, if a user deletes any comment, that comments get deleted but the id referenced in the Post Model still remains. Though it is not active but it remains there. In a situation where you have many comments that get deleted, that Post collection with the Comment referenced field will look messy. Is there a way around this? I want once a comment is deleted, it should also delete anywhere it is referenced. Here are my codes:
Post Model
//creating the user models for the database
const mongoose = require("mongoose"); //import mongoose
const Schema = mongoose.Schema;
const PostSchema = new mongoose.Schema(
{
title:{
type: String,
required: true,
unique: true,
},
description:{
type: String,
required: true,
},
postPhoto:{
type: String,
required:false,
},
username:{
type: Schema.Types.ObjectId,
ref: 'User'
},
categories:{
type: Array,
},
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment',
unique: true,
}]
}, {timestamps: true},
);
//exporting this schema
module.exports = mongoose.model("Post", PostSchema); //the module name is "Post"
Comment Model
const mongoose = require("mongoose"); //import mongoose to be used
const Schema = mongoose.Schema;
const CommentSchema = new mongoose.Schema(
{
commentdescription:{
type: String,
required: true,
},
author:{
type: Schema.Types.ObjectId,
ref: 'User',
},
}, {timestamps: true}
);
//exporting this schema
module.exports = mongoose.model("Comment", CommentSchema); //the module name is "Post"
Codes that delete a comment
//comment delete
router.delete("/posts/:id/comment/:id", async (req, res) =>{
try{
const comment = await Comment.findById(req.params.id)
if(comment.author == req.body.author){
try{
await comment.delete()
res.status(200).json("Comment has been deleted")
}catch(err){
console.log(err)
}
}
else{
res.status(401).json("you can only delete your comment")
}
}catch(err){
console.log(err)
}
})
codes that populates comment in Post
//Get Post
router.get("/:id", async(req, res)=>{
try{
const post = await Post.findById(req.params.id).populate('username').populate({
path: "comments",
populate: {
path: "author",
}
})
See the attached image. You can see that comment field in Post collection is still with a comment ref that has been deleted. The comment is deleted from the Comment Collection. But I will also like to delete all places it is referenced.
my main language is not English, so I apologize for that
Some things need to be corrected
Post Model
const mongoose = require("mongoose"); //import mongoose
const Schema = mongoose.Schema;
const PostSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
unique: true,
},
description: {
type: String,
required: true,
},
postPhoto: {
type: String,
required: false,
},
// Commented for testing
// username: {
// type: Schema.Types.ObjectId,
// ref: "User",
// },
categories: {
type: Array,
},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment",
unique: true,
},
],
},
{ timestamps: true }
);
//exporting this schema
module.exports = mongoose.model("Post", PostSchema);
Comment Model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const CommentSchema = new mongoose.Schema(
{
commentdescription: {
type: String,
required: true,
},
// Commented for testing
// author: {
// type: Schema.Types.ObjectId,
// ref: "User",
// },
postId: {
type: Schema.Types.ObjectId,
ref: "Post",
},
},
{ timestamps: true }
);
module.exports = mongoose.model("Comment", CommentSchema);
index.js
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true }));
const port = 3000;
var mongoDB = "mongodb://127.0.0.1/my_database";
mongoose.connect(mongoDB);
const Post = require("./Model/Post");
const Comment = require("./Model/Comment");
// add post
app.post("/posts/add", async (req, res) => {
console.log(req.body);
const post = await Post.create(req.body);
res.status(200).json({
success: true,
data: post,
});
});
// add comment
app.post("/comment/add", async (req, res) => {
const comment = await Comment.create(req.body);
const post = await Post.findByIdAndUpdate(
{ _id: comment.postId },
{
$addToSet: { comments: comment._id },
}
);
res.status(200).json({
success: true,
data: comment,
});
});
// get all post
app.get("/posts", async (req, res) => {
const post = await Post.find({});
res.status(200).json({
post,
});
});
// delete comment
app.delete("/comment/:id", async (req, res) => {
const com = await Comment.findById(req.params.id);
console.log("postid", com.postId);
await Post.findByIdAndUpdate(
{ _id: com.postId },
{
$pull: { comments: com._id },
},
{ new: true }
);
await com.delete();
res.status(200).json({
success: true,
});
});
app.listen(port, () => {
console.log("server connect");
});
Models are not smart to understand your intention that because you
deleted the comment, they should be deleted from everywhere.
Computers are stupid, you have to explain to them face to face.
In this application, I am trying to update a field value, if it is successful then I want to save into a log collection, however, not all the data are saved in the log collection, I am not sure if I am doing it the right way, would appreciate if someone could help out.
here is the query :
// both models(Log & Inventory are imported)
router.get("/add_product/:id/:num/:quantity/:order", (req, res) => {
var id = req.params.id;
var quantity = req.params.quantity;
var order = req.params.order;
// console.log('id----', id);
var num_mod = req.params.num;
var modified_count = parseInt(num_mod) - parseInt(quantity);
console.log("num_mod----", num_mod);
Inventory.findByIdAndUpdate(id, { quantity: parseInt(num_mod) }, { new: true }, function(
err,
inventory
) {
if (err) {
console.log("err", err);
res.status(500).send(err);
} else {
console.log(inventory.name);
const newLog = new Log({
name: inventory.name,
description: inventory.description,
price: parseInt(inventory.price),
quantity: parseInt(inventory.quantity),
modified_quantity: parseInt(modified_count),
itemDest: order //this is not being saved
});
newLog.save(function(err, Log) {
if (err) {
console.log(err);
} else {
console.log("add log success");
res.send(inventory);
}
});
}
});
});
URL from front end :
// order is a string
here is the Log schema :
const mongoose = require("mongoose");
const LogSchema = new mongoose.Schema(
{
// _id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
quantity: { type: Number, required: true },
modified_quantity: { type: Number, required: true },
supplier: String,
taxable: Boolean,
itemDest: String
},
{ timestamps: true }
);
// Create model from the schema
const Log = mongoose.model("Log", LogSchema);
// Export model
module.exports = Log;
and here is the inventory schema
const mongoose = require("mongoose");
//create Schema
const InventorySchema = new mongoose.Schema(
{
// _id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
quantity: { type: Number, required: true },
supplier: String,
taxable: Boolean
},
{ timestamps: true }
);
// Create model from the schema
const Inventory = mongoose.model("Inventory", InventorySchema);
// Export model
module.exports = Inventory;
My issue is with this line "itemDest: order" in the query, I intend to save the value of "order" extracted from "req.params.order" into "itemDest" but it doesn't save.
I want to insert my book to Collection Book. In book, i have field author is a part of another Collection called Author. I try to insert the book but i got Mongoose casterror. This is my code:
const mongoose = require('mongoose')
const path = require('path')
const coverImageBasePath = 'uploads/bookCovers'
const bookSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String
},
publishDate: {
type: Date,
required: true
},
pageCount: {
type: Number,
required: true
},
createdAt: {
type: Date,
required: true,
default: Date.now
},
coverImageName: {
type: String,
required: true
},
author: {
type: mongoose.Types.ObjectId,
required: true,
ref: 'Author'
}
})
module.exports = mongoose.model('Book', bookSchema)
And this is post router to create a book
router.post('/', upload.single('cover'), async (req, res) => {
const fileName = req.file != null ? req.file.filename : null
const book = new Book({
title: req.body.title,
author: req.body.author,
publishDate: new Date(req.body.publishDate),
pageCount: req.body.pageCount,
coverImageName: fileName,
description: req.body.description
})
try {
const newBook = await book.save()
// res.redirect(`books/${newBook.id}`)
res.redirect(`books`)
} catch (err) {
console.log(err)
if (book.coverImageName != null) {
removeBookCover(book.coverImageName)
}
renderNewPage(res, book, true)
}
})
async function renderNewPage(res, book, hasError = false) {
try {
const authors = await Author.find({})
const params = {
authors: authors,
book: book
}
if (hasError) params.errorMessage = 'Error Creating Book'
res.render('books/new', params)
} catch {
res.redirect('/books')
}
}
I tried some solution and googled but it did not work, when i insert straightly author by String, it works so i think the bug is in the mongoose Schema but i can not find out the way to solve it. Please help me.
I am trying to make a One-To-Many relationship between two tables(Group and Movement tables) using node js (Express) and mongo DB. I already have a group Id coming from the Group table on my side, my question is, how can I save a movement( see point 3 ) with that group Id I have. I tried passing groupId: req.body.group._id and
groupId: req.body.group but I am never able to populate that variable
This are the two entities I've created:
1) GROUP ENTITY
const mongoose = require("mongoose")
const GroupSchema = mongoose.Schema({
name: {
type: String,
required: true
},
limit: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
movement: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Movement' }],
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
})
module.exports = mongoose.model("Group", GroupSchema)
2) MOVEMENT ENTITY
const mongoose = require("mongoose")
const MovementSchema = mongoose.Schema({
description: {
type: String,
required: true
},
value: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
group: { type: mongoose.Schema.Types.ObjectId, ref: 'Group' }
})
module.exports = mongoose.model("Movement", MovementSchema)
This is my movement router where I make the endpoints (Actual problem is here)
3) MovementRoute
const router = require('express').Router();
const verify = require('./verifyToken');
const User = require('../model/User');
const Group = require('../model/Group');
const Movement = require('../model/Movement');
// Create Movement
router.post('/', verify, async (req, res) => {
const post = new Movement({
description: req.body.description,
value: req.body.value,
groupId: req.body.group._id //**tried this**
});
try {
const savedMovement = await post.save()
res.status(200).send(res.json({ data: savedMovement }));
} catch (error) {
res.status(400).send(res.json({ message: error }));
}
});
module.exports = router;
Request sent
{
"description":"group1",
"value":"233",
"group":"5e506f3c56233d08f79bc8f3"
}
If console.log(req.body) gives you this:
{
description: 'group1',
value: '233',
group: '5e506f3c56233d08f79bc8f3'
}
..you should be able to do this:
router.post('/', verify, async (req, res) => {
console.log(req.body) // --> { description: 'group1', value: '233', group: '5e506f3c56233d08f79bc8f3' }
const post = new Movement({
description: req.body.description,
value: req.body.value,
groupId: req.body.group
// groupId: req.body.group._id //**tried this**
});
try {
const savedMovement = await post.save()
res.status(200).send(res.json({ data: savedMovement }));
} catch (error) {
res.status(400).send(res.json({ message: error }));
}
});
I've got the following mongoose models:
Place.js
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const placeSchema = new Schema({
title: { type: String, require: true },
filename: { type: String, require: true },
lociSets: [{ type: Schema.Types.ObjectId, ref: 'LociSet'}]
})
module.exports = mongoose.model("places", placeSchema)
LociSet.js
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const LociSchema = require('./Locus')
const lociSetSchema = new Schema({
title: { type: String, require: true },
creator: { type: Schema.Types.ObjectId, ref: 'User' },
public: { type: Boolean, default: true },
loci: [LociSchema]
})
module.exports = mongoose.model("lociSets", lociSetSchema)
Locus.js
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const locusSchema = new Schema({
position: {
x: { type: Number, require: true },
y: { type: Number, require: true },
z: { type: Number, require: true }
}
})
module.exports = locusSchema
Problem:
I try to insert a new LociSet into the lociSet array of Place like so:
exports.createOne = async (req, res) => {
const {
title,
public = true,
loci = []
} = req.body
console.log(title,public,loci,req.user.id)
const lociSet = new LociSet({
title,
public,
loci,
creator: req.user.id
})
try {
const place = await Place.findOne({
"title": req.params.title.toLowerCase()
})
console.log(lociSet)
await lociSet.save()
await place.lociSets.push(lociSet)
await place.save()
} catch (err) {
res.status(500).send({
message: "Some error occurred while creating the loci set.", err
});
}
}
But then I get an error message saying "Cast to [undefined] failed for value \"[{\"title\":\"Test set\",\"creator\":\"5a7898c403999200c4ee3ae5\",\"public\":\"true\"}]\" at path \"lociSets\""
The LociSet model is created without problems, but it seems to break when I try to save the place model
Because lociSets is an array of ObjectId references, you may want to try the following approach:
exports.createOne = async (req, res) => {
const { title, public = true, loci = [] } = req.body
const lociSet = new LociSet({
title,
public,
loci,
creator: req.user.id
})
try {
const newLociSet = await lociSet.save()
const place = await Place.findOneAndUpdate(
{ "title": req.params.title.toLowerCase() },
{ "$push": { "lociSets" : newLociSet._id } },
{ "new": true}
)
res.status(200).json(place)
} catch (err) {
res.status(500).send({
message: "Some error occurred while creating the loci set.", err
})
}
}