从对象中删除不在类中的属性

时间:2019-06-15 18:27:53

标签: javascript node.js adonis.js

我正在使用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中所述的验证程序设置,但仍然允许其他属性绕过它。

3 个答案:

答案 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",
    ]);
  }