Today we will look about how to build up a relation with
mongoose and dig deep into its important functions such as populate(), search()
and also I’m going to discuss about authentication briefly.
Let’s
Create a User Model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
cart: {
items: [
{
productId: { type: Schema.Types.ObjectId ,ref: "Product" },
//ref defines the
relation (with Product collection)
quantity: { type: Number, required: true },
},
],
},
});
module.exports = mongoose.model("User", userSchema);
in App.js
mongoose
.connect("mongodb://localhost:27017/nodefirst", {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
User.findOne().then((user) => {
if (!user) {
const user = new User({ //New user Hard-coded
just for now
name: "Yasas",
email: "yasassandeepa@gmail.com",
cart: { items: [] },
});
user.save();
}
});
app.listen(3000);
console.log("Server running at http://127.0.0.1:3000/");
})
.catch((err) => {
console.log(err);
});
In App.js => before all middleware’s
app.use((req, res, next) => {
User.findById("5eb761eb25c47749443eca0c")//user id that created
prev
.then((user) => {
console.log(user);
req.user = user;
next();
})
.catch((err) => {
console.log(err);
});
});
Setting References - Relations
In Products
model we add a new field to reference the user.
userId:{
type: Schema.Types.ObjectId,
ref:'User' //refer
the user Model
},
then when
adding the product -> we can pass his id (or complete user)
product controller
exports.postAddProduct = (req, res, next) => {
const title = req.body.title;
const imgUrl = req.body.imgUrl;
const price = req.body.price;
const description = req.body.description;
const product = new Product({
title: title,
price: price,
description: description,
imgUrl: imgUrl,
userId: req.user,
//here
we adding the user (but mongoose automatically take user id)
});
product
.save()
.then((result) => {
console.log(result);
res.redirect("/");
})
.catch((err) => {});
};
Mongoose
Special -> Populate()
This will generate user data with relevant to user Id in one
request.
Populate() will automatically fetch relevant id data.
exports.getProducts = (req, res, next) => {
Product.find()
.populate("userId")
.then((products) => {
console.log(products);
/*{ _id:
5eb764ebd29acc214436f815,
title: 'New Prod',
price: 65,
description: 'Des 1',
imgUrl: 'ssdsd',
userId:
//not returning the id but returning the relevant data also //very
IMP
{ cart: [Object],
_id: 5eb763325e918a55dca33e11,
name: 'Yasas',
email: 'yasassandeepa@gmail.com',
__v: 0 },
__v: 0 }*/
})
.catch((err) => {});
};
.select()
we can
select what are the fields we want by
exports.getProducts = (req, res, next) => {
Product.find()
.select("title price -_id") //minus sign for
excludes
.populate("userId","name")
.then((products) => {
console.log(products);
/*
[ { title: 'New Prod',
price: 65,
userId: { _id: 5eb763325e918a55dca33e11,
name: 'Yasas' } } ]
*/
})
.catch((err) => {});
};
Authorization
-> lock down the access
Fetching
data relevant to the user.
exports.getAdminProducts = async (req, res, next) => {
Product.find({ userId: req.user._id })
.then((products) => {
res.render("admin/products", {
prods: products,
pageTitle: "Admin Product List",
hasProducts: products.length > 0,
active: "adminProducts",
});
})
.catch((err) => {
console.log(err);
});
};
When Editing
a product
if(product.userId.toString() !== req.user._id){
res.redirect('/');
}
when Deleting
a product
exports.postDeleteProduct = (req, res, next) => {
const prodId = req.body.productId;
Product.deleteOne({_id:prodId,userId:req.user._id})
// lets match it for the
both userid and product id
.then(() => {
return res.redirect("/admin/products");
})
.catch((err) => {});
};

0 Comments