我有一个记录列表,我希望使用各个表单字段中的调整值进行批量更新。当我尝试运行POST并根据输入中的值更新记录时,我在Where子句中遇到错误,我想知道如何解析where discoverySourceId
的where子句或者什么将是我当前设置中使用的最佳方法。
Error: Missing where attribute in the options parameter passed to update.
路线:
var appRoutes = express.Router();
var _ = require('lodash-node');
var async = require('async');
var models = require('../models/db-index');
appRoutes.route('app/settings/discovery-sources')
.get(function(req, res){
models.DiscoverySource.findAll({
where: {
organizationId: req.user.organizationId
}, attributes: ['discoverySourceId', 'discoverySourceName']
}).then(function(discoverySource){
res.render('pages/app/settings-discovery-sources.hbs', {
discoverySource: discoverySource
});
})
})
.post(function(req, res){
console.log('POST Triggered');
var sources = _.map(req.body.discoverySourceName, function (source) {
return {
discoverySourceName: source,
discoverySourceId: req.body.discoverySourceId
};
});
models.DiscoverySource.update(sources).then(function(){
console.log("Successful update");
res.redirect('/settings/discovery-sources');
});
});
**Form:**
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="annotation-form">
<h2>Discovery Sources</h2>
<form action="/app/settings/discovery-sources" method="post">
{{#each discoverySource}}
<input type="hidden" name="discoverySourceId" value={{this.discoverySourceId}}>
<input type="text" name="discoverySourceName[0]" value="{{this.discoverySourceName}}"><a href="#" id="settings-delete-discovery-source">Delete</a>
<br />
{{else}}
<p>No Discovery Sources</p>
{{/each}}
<button type="submit">Update Sources</button>
</form>
</div>
</div>
</div>
discoverySource:
module.exports = function(sequelize, DataTypes) {
var DiscoverySource = sequelize.define('discovery_source', {
discoverySourceId: {
type: DataTypes.INTEGER,
field: 'discovery_source_id',
autoIncrement: true,
primaryKey: true,
notNull: true,
},
discoverySourceName: {
type: DataTypes.STRING,
field: 'discovery_source_name'
},
organizationId: {
type: DataTypes.TEXT,
field: 'organization_id'
},
},{
freezeTableName: true
});
return DiscoverySource;
}
答案 0 :(得分:2)
var appRoutes = express.Router();
var _ = require('lodash-node'); // just use lodash, using lodash-node is deprecated and it's redundant.
var async = require('async');
var models = require('../models/db-index');
// Added these for context
var app = express();
var Promise = require('bluebird'); // or Q if you prefer.
// Make sure you're using body-parser urlencoded
// with extended set to true. This allows us to have
// fancy body parsing for forms.
// This line must be above all your routes.
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: true
}))
appRoutes.route('app/settings/discovery-sources')
.get(function (req, res) {
models
.DiscoverySource
.findAll({
where: {
organizationId: req.user.organizationId
},
attributes: ['discoverySourceId', 'discoverySourceName']
})
.then(function (discoverySource) {
res.render('pages/app/settings-discovery-sources.hbs', {
discoverySource: discoverySource
});
})
})
.post(function (req, res) {
console.log('POST Triggered');
// We use promise.map to map the array in the body into an array of promises
// which are resolved when each promise has been resolved.
// It's a good idea here to use sequelize.transaction() so that if one update
// fails, everything gets rolled back.
// If you're using Q it doesn't support .map() so this looks slightly different in that case.
// q.all(_.map(req.body.discoverySources, function() {}))
Promise
.map(req.body.discoverySources, function (source) {
return models
.DiscoverySource
.update({
discoverySourceName: source.name
}, {
// We have to call update with the ID of each discoverySource so that
// we update the names of each discovery source correctly.
where: {
discoverySourceId: source.id
}
})
})
.then(function () {
console.log("Successful update");
res.redirect('/settings/discovery-sources');
});
});
HTML
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="annotation-form">
<h2>Discovery Sources</h2>
<form action="/app/settings/discovery-sources" method="post">
{{#each discoverySource}}
<!-- Use body parser urlencoded syntax so the request body is parsed into an array of objects with the
properties id and name. See the qs library for syntax documentation, https://www.npmjs.com/package/qs#readme -->
<input type="hidden" name="discoverySources[][id]" value={{this.discoverySourceId}}>
<input type="text" name="discoverySources[][name]" value="{{this.discoverySourceName}}"><a href="#" id="settings-delete-discovery-source">Delete</a>
<br /> {{else}}
<p>No Discovery Sources</p>
{{/each}}
<button type="submit">Update Sources</button>
</form>
</div>
</div>
</div>
答案 1 :(得分:0)
只需添加@GrimurD答案 - 如果您在更新时想要获取更新的数据,则可以执行以下操作:
Promise
.all(_.map(clients, (client) => {
const { firstName, lastName, phoneNumber, emailAddress } = client;
return Client
.update({
firstName,
lastName,
phoneNumber,
emailAddress,
}, {
where: {
id: client.id,
},
returning: true,
plain: true,
});
}))
.then((results) => {
// do whatever you want with the returned results
const updatedClients = results.map(result => _.omit(result[1].dataValues, ['salt', 'password']));
callback(null, updatedClients);
})
.catch((err) => {
callback({ error: true, message: err.message ? err.message : 'Unable to fetch updated user details' });
});
因此,所有更新的记录都将作为一个对象数组返回,您可以使用该数据执行任何操作。