sequelize 忽略 JSON 对象上的“save()”方法

tab*_*ena 2 javascript sqlite node.js sequelize.js

我正在尝试利用模型实例方法的优势,如文档中所述。所以我将User类定义如下:

class User extends Model {
    addRole(role){
        let roles = this. roles;
        roles[role] = true;
        this.roles = roles;
        this.save();
    }

    removeRole (role) {
        let roles = this.roles;
        delete roles[role];
        this.save();
    }
    
    hasRole (role){
        return this.roles[role] != null;
    }
}


User.init({
// some attributes
,
roles:{
  type: DataTypes.JSON,
  allowNull: false,
}
}, { sequelize});
Run Code Online (Sandbox Code Playgroud)

我希望在任何情况下都使用方法addRole(), 。removeRole()hasRole()User

所有方法都无法将更改保存到数据库的问题。(只能读取!)

// example 
let user = null; 
// get the first user to test.
User.findAll() 
    .then(users =>{
          user = users[0];
          user.addRole("admin");
          console.log(user.roles); // {admin: true} 
          user.save();
          // However the changes don't appear in the database.
}); 
Run Code Online (Sandbox Code Playgroud)

tab*_*ena 7

我已经找到答案了。由于某些原因,sequelise无法正确检测json对象的变化。As在内部进行了优化,如果模型没有更改,sequelise则忽略对的调用。model.save()所以,sequelize随机忽略该save方法。

正如我第一次遇到这个问题时所相信的那样,这种行为与实例方法无关。

为了摆脱这个问题,我不得不使用:

 user.addRole("admin");
 user.changed("roles", true); // <<<< look at this;
 console.log(user.roles); // {admin: true} 
 user.save();
Run Code Online (Sandbox Code Playgroud)

请注意,当手动编辑嵌套(例如 JSON)属性中的属性时,此函数将返回 false,在这些情况下您必须手动调用changed('key', true)。将检测到写入全新的对象(例如深度克隆)。

例子:

const mdl = await MyModel.findOne();
mdl.myJsonField.a = 1;
console.log(mdl.changed()) => false
mdl.save(); // this will not save anything
mdl.changed('myJsonField', true);
console.log(mdl.changed()) => ['myJsonField']
mdl.save(); // will save
Run Code Online (Sandbox Code Playgroud)

改变了方法的使用