我正在使用adonisjs,并试图清理服务器上的发布请求。我获取的数据具有未映射到表/模型的额外属性,因此在尝试保存时出错。这是更新方法
async update ({ params, request, response }) {
const contract = await Contract.find(params.id);
contract.merge(request.post());
return await contract.save();
}
问题在于,当我较早时在get请求中退还合同时,我添加了一些计算属性。我可以按照
的方式做一些事情const { prop1, prop2 } = request.post();
但这并不代表未来的解决方案或干净的解决方案。理想情况下,我希望对象仅具有在表/模型上定义的属性。我有the validator docs中所述的验证程序设置,但仍然允许其他属性绕过它。
答案 0 :(得分:0)
帮手课怎么样?
class RequestContractExtractor{
static desiredProps = [
"prop1",
"prop2",
]; // you could replace this with a list you get from your model class
constructor(requestData){
desiredProps.forEach(prop => this[prop] = requestData[prop]);
}
static from(...args){ return new this(...args); }
}
那么您将能够做到:
async update ({ params, request, response }) {
const contract = await Contract.find(params.id);
contract.merge(RequestContractExtractor.from(request.post()));
return await contract.save();
}
答案 1 :(得分:0)
我通过在模型类中添加一个beforeSave钩子来解决此问题,该钩子过滤对象上的属性,这使我们可以保留一个瘦控制器。
const FIELDS = ['id', 'description'];
class Contract extends Model {
static boot() {
super.boot();
this.addHook('beforeSave', async contractInstance => {
Object.keys(contractInstance.$attributes).forEach(key => {
if (!CONTRACT_FIELDS.includes(key)) {
delete contractInstance.$attribute[key];
}
});
});
}
}
答案 2 :(得分:0)
我通过添加一个 beforeSave 钩子来解决这个问题,该钩子可以过滤对象的属性。
在 /app/Model/Hooks/ContractHook.js
处创建文件
'use strict'
const ContractHook = module.exports = {}
const CONTRACT_FIELDS = ["id", "description"];
ContractHook.removeDynamicFields = async (contractInstance) => {
if (contractInstance) {
Object.keys(contractInstance.$attributes).forEach((key) => {
if (!CONTRACT_FIELDS.includes(key) && contractInstance.$attributes[key]) {
delete contractInstance.$attributes[key];
}
});
}
};
像这样在你的模型中使用它......
class Contract extends Model {
static boot() {
super.boot();
this.addHook("beforeCreate", [
"ContractHook.removeDynamicFields",
]);
}