使用 Mongoose、Express、NodeJS 更新模型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5024787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Update model with Mongoose, Express, NodeJS
提问by JohnAllen
I'm trying to update an instantiated model ('Place' - I know it works from other routes) in a MongoDB and have spent a while trying to properly do so. I'm also trying to redirect back to the page that views the 'place' to view the updated properties.
我正在尝试更新 MongoDB 中的实例化模型('Place' - 我知道它可以从其他路由运行),并且花了一段时间尝试正确执行此操作。我还尝试重定向回查看“地点”的页面以查看更新的属性。
Node v0.4.0, Express v1.0.7, Mongoose 1.10.0
Node v0.4.0、Express v1.0.7、Mongoose 1.10.0
Schema:
架构:
var PlaceSchema = new Schema({
name :String
, capital: String
, continent: String
});
Controller/route:
控制器/路由:
app.put('/places/:name', function(req, res) {
var name = req.body.name;
var capital = req.body.capital;
var continent = req.body.continent;
Place.update({ name: name, capital: capital, continent: continent}, function(name) {
res.redirect('/places/'+name)
});
});
});
I've tried a bunch of different ways but can't seem to get it.
Also, isn't how I declare the three {name, capital, and continent} variables blocking further operations? Thanks. General debugging help is also appreciated. Console.log(name) (right below the declaration) doesn't log anything.
我尝试了很多不同的方法,但似乎无法得到它。
另外,我声明三个 {name, capital, and continent} 变量的方式不是阻止进一步操作吗?谢谢。还感谢一般调试帮助。Console.log(name) (在声明的正下方)不记录任何内容。
Jade form:
玉形态:
h1 Editing #{place.name}
form(action='/places/'+place.name, method='POST')
input(type='hidden', name='_method', value='PUT')
p
label(for='place_name') Name:
p
input(type='text', id='place_name', name='place[name]', value=place.name)
p
label(for='place_capital') Capital:
p
input(type='text', id='place_capital', name='place[capital]', value=place.capital)
p
label(for='place_continent') Continent:
p
textarea(type='text', id='place_continent', name='place[continent]')=place.continent
p
input(type="submit")
回答by schaermu
You have to find the document before updating anything:
您必须在更新任何内容之前找到该文档:
Place.findById(req.params.id, function(err, p) {
if (!p)
return next(new Error('Could not load Document'));
else {
// do your updates here
p.modified = new Date();
p.save(function(err) {
if (err)
console.log('error')
else
console.log('success')
});
}
});
works for me in production code using the same setup you have. Instead of findById you can use any other find method provided by mongoose. Just make sure you fetch the document before updating it.
使用您拥有的相同设置在生产代码中对我来说有效。您可以使用 mongoose 提供的任何其他查找方法代替 findById。只需确保在更新文档之前获取文档。
回答by k33g_org
Now, i think you can do this :
现在,我认为你可以这样做:
Place.findOneAndUpdate({name:req.params.name}, req.body, function (err, place) {
res.send(place);
});
You can find by id too :
您也可以通过 id 找到:
Place.findOneAndUpdate({_id:req.params.id}, req.body, function (err, place) {
res.send(place);
});
回答by Abhishek Gupta
So now you can find and update directly by id, this is for Mongoose v4
所以现在你可以直接通过id查找和更新,这是针对Mongoose v4的
Place.findByIdAndUpdate(req.params.id, req.body, function (err, place) {
res.send(place);
});
Just to mention, if you needs updated object then you need to pass {new: true}like
只是提一下,如果你需要更新的对象,那么你需要{new: true}像
Place.findByIdAndUpdate(req.params.id, req.body, {new: true}, function (err, place) {
res.send(place);
});
回答by Derya Cortuk
you could do something similar based on the illustration below
你可以根据下图做类似的事情
Updated:
更新:
In My solution: I have created a model, controller and route to depict the similar scenario (interacting with MongoDB method like updating/creating data to the database)in Nodejs MVC framework with MongoDB as the database
在我的解决方案中:我创建了一个模型、控制器和路由来描述(interacting with MongoDB method like updating/creating data to the database)Nodejs MVC 框架中以 MongoDB 作为数据库的类似场景
// user.js - this is the user model
const mongoose = require('mongoose')
const validator = require('validator')
const User = mongoose.model('User', {
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
password: {
type: String,
required: true,
minlength: 7,
trim: true,
validate(value) {
if (value.toLowerCase().includes('password')) {
throw new Error('Password cannot contain "password"')
}
}
},
age: {
type: Number,
default: 0,
validate(value) {
if (value < 0) {
throw new Error('Age must be a positive number')
}
}
}
});
module.exports = User
// userController.js**
exports.updateUser = async(req, res) => {
const updates = Object.keys(req.body)
const allowedUpdates = ['name', 'email', 'password', 'age']
const isValidOperation = updates.every((update) => {
allowedUpdates.includes(update))
if (!isValidOperation) {
return res.status(400).send('Invalid updates!')
}
try {
const user = await UserModel.findByIdAndUpdate(req.params.id,
req.body, { new: true, runValidators: true })
if (!user) {
return res.status(404).send({ message: 'You do not seem to be registered' })
}
res.status(201).send(user)
} catch (error) {
res.status(400).send(error)
}
}
// **router.js**
router.patch('/user/:id', userController.updateUser)
I hope this would help anyone, you can also Read more.
我希望这会帮助任何人,你也可以阅读更多。
回答by Chris
I think your problem is that you are using node 0.4.0 - try moving to 0.2.6 with an it should work. There is an issue logged on github with the bodyDecoder not populating the req.body.variable field in node >= 0.3.0.
我认为您的问题是您正在使用节点 0.4.0 - 尝试移动到 0.2.6,它应该可以工作。在 github 上记录了一个问题,bodyDecoder 未填充节点 >= 0.3.0 中的 req.body.variable 字段。

