如何更新排除字段的 Sequelize 模型

thu*_*hur 3 sequelize.js

纵观Sequelize文档,我觉得如何指定哪些字段我想更新,但我想指定哪些字段我希望更新。

类似的东西:
Model.update(,{excludeFields:['id']})

有没有办法做到这一点?

Moh*_*mel 6

TL;DR 获取所有字段,然后排除您不想要的字段。

const fieldsToExclude = ['password', 'sensitive_info', 'attribute_not_allowed_due_to_user_role']    
const myFields = Object.keys(MyModel.rawAttributes).filter( s => !fildsToExclude.includes(s))
MyModel.update(newValue, {fields: myFields})
Run Code Online (Sandbox Code Playgroud)

如果你问(你应该问)我从哪里得到这个,它不在文档中!继续阅读。

一些细节
虽然我真的很喜欢 Sequelize,但我承认他们的参考资料有时缺乏一些信息。

例如,findByPk内部调用findOnewhich 内部调用的事实findAll,这意味着options传递给的对象findAll也适用于findOnefindByPk

不幸的是,update方法不像函数族那样处理options对象find*。下面是如何update处理对象的fields属性options

// Remove values that are not in the options.fields
    if (options.fields && options.fields instanceof Array) {
      for (const key of Object.keys(values)) {
        if (options.fields.indexOf(key) < 0) {
          delete values[key];
        }
      }
    } else {
      const updatedAtAttr = this._timestampAttributes.updatedAt;
      options.fields = _.intersection(Object.keys(values), Object.keys(this.tableAttributes));
      if (updatedAtAttr && options.fields.indexOf(updatedAtAttr) === -1) {
        options.fields.push(updatedAtAttr);
      }
    }
Run Code Online (Sandbox Code Playgroud)

另一方面,find*function 最终会通过_.confirmOptions()which will call _expandAttributes(),实现如下:

  static _expandAttributes(options) {
    if (_.isPlainObject(options.attributes)) {
      let attributes = Object.keys(this.rawAttributes);

      if (options.attributes.exclude) {
        attributes = attributes.filter(elem => {
          return options.attributes.exclude.indexOf(elem) === -1;
        });
      }
      if (options.attributes.include) {
        attributes = attributes.concat(options.attributes.include);
      }

      options.attributes = attributes;
    }
  }
Run Code Online (Sandbox Code Playgroud)

这就是“排除”逻辑发生的地方。

HTH