用户模型
const mongoose = require("mongoose");
const validator = require("validator");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const Task = require("./tasks");
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
trim: true
},
age: {
type: Number,
default: 0,
validate(val) {
if (val < 0) throw new Error("age must be a positive number");
}
},
email: {
type: String,
unique: true, //If you use this when you already have data in your db you need to re-populate the db or else it wont work
required: true,
trim: true,
lowercase: true,
validate(val) {
if (!validator.isEmail(val)) throw new Error("Invalid Email");
}
},
password: {
type: String,
minlength: 6,
required: true,
trim: true,
validate(val) {
if (val.includes("password"))
throw new Error("password cant contain password");
}
},
tokens: [
{
token: {
type: String,
required: true
}
}
]
},
{
timestamps: true
}
);
userSchema.virtual("tasks", {
ref: "Task",
localField: "_id",
foreignField: "owner"
});
// Custom function to find user by email and password
// N.B :- we use ".statics for create model functions"
userSchema.statics.findByCredentials = async (email, password) => {
const user = await User.findOne({ email });
if (!user) {
throw new Error("Unable to login");
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
throw new Error("Unable to login");
}
return user;
};
// Hash plain text password before saving
userSchema.pre("save", async function(next) {
const user = this;
if (user.isModified("password")) {
user.password = await bcrypt.hash(user.password, 8);
}
next();
});
//Middleware to delete all user tasks when the user is deleted
userSchema.pre("remove", async function(next) {
const user = this;
await Task.deleteMany({ owner: user._id });
next();
});
//Custom function to create a jwt token for a specific user
// N.B:- we use ".methods" to create instance methods
userSchema.methods.generateAuthToken = async function() {
const user = this;
const token = jwt.sign({ _id: user._id.toString() }, "mysupersecurestring");
user.tokens = user.tokens.concat({ token });
await user.save();
return token;
};
userSchema.methods.toJSON = function() {
const user = this;
const userObject = user.toObject();
delete userObject.password;
delete userObject.tokens;
return userObject;
};
const User = mongoose.model("User", userSchema);
module.exports = User;
任务模型
const mongoose = require("mongoose");
const taskSchema = new mongoose.Schema(
{
description: {
type: String,
required: true,
trim: true
},
completed: {
type: Boolean,
default: false
},
owner: {
type: mongoose.Schema.Types.ObjectId, //use toHexString() to convert to string to avoid errors
required: true,
ref: "User"
}
},
{
timestamps: true //timestamps (plural)
}
);
const Task = mongoose.model("Task", taskSchema);
module.exports = Task;
任务控制器
const express = require("express");
const Task = require("../models/tasks");
const auth = require("../middleware/auth");
const router = new express.Router();
router.post("/tasks", auth, async (req, res) => {
//const task = new Task(req.body);
const task = new Task({
...req.body,
owner: req.user._id
});
try {
await task.save();
return res.status(201).send(task);
} catch (e) {
console.log(e);
// return res.send(e);
}
});
router.get("/tasks", auth, async (req, res) => {
try {
//const allTasks = await Task.find({ owner: req.user._id.toHexString() });
await req.user
.populate({
path: "tasks",
match: {
completed: false
}
})
.execPopulate();
res.send(req.user.tasks);
//res.send(allTasks);
} catch (e) {
res.status(500).send();
}
});
router.get("/tasks/:id", auth, async (req, res) => {
const _id = req.params.id;
try {
const task = await Task.findOne({ _id, owner: req.user._id.toHexString() });
//console.log(_id, req.user._id.toHexString(), task);
if (!task) {
return res.status(404).send();
}
res.send(task);
} catch (e) {
res.status(500).send();
}
});
router.patch("/tasks/:id", auth, async (req, res) => {
const updates = Object.keys(req.body);
const allowedUpdates = ["description", "completed"];
const isValidOperation = updates.every(update =>
allowedUpdates.includes(update)
);
if (!isValidOperation)
return res.status(400).send({ error: "invalid updates!" });
try {
//const task = await Task.findByIdAndUpdate(req.params.id, req.body, {new: true,runValidators: true});
const task = await Task.findOne({
_id: req.params.id,
owner: req.user._id
});
if (!task) return res.status(404).send();
updates.forEach(update => {
task[update] = req.body[update];
});
await task.save();
return res.send(task);
} catch (e) {
return res.status(400).send(e);
}
});
router.delete("/tasks/:id", auth, async (req, res) => {
try {
const task = await Task.findOneAndDelete({
_id: req.params.id,
owner: req.user._id
});
if (!task) return res.status(404).send();
res.send(task);
} catch (e) {
res.status(500).send(e);
}
});
module.exports = router;
在任务控制器中,当我尝试使用路由器时,get(/tasks)一直显示错误500(内部服务器错误)。我尝试填充用户模型中的虚拟属性,即任务。get任务路由处理程序旨在返回特定用户创建的所有任务
1条答案
按热度按时间brqmpdu11#
如果您的mongoose版本是
>=6.0
,则execPopulate()
不再存在。参考已删除execPopulate()。希望它能解决你问题。