node.js - 如何使用 beforeUpdate Hook Sequelize 中止更新操作

标签 node.js sequelize.js

我如何在 sequelize 上使用 beforeUpdate 钩子(Hook)中止更新操作并返回一个对象作为中止更新的结果,

如果我有类似的东西:

User.beforeUpdate(function(user, options) {
  if (user.name == "example_name") {
  // abort operation here 
  // return object to the update caller
  }
}

最佳答案

throw 在钩子(Hook)阻止更新之前

例如:

  beforeUpdate: (integerName, options) => {
    if (integerName.value === 5) {
      throw new Error('beforeUpdate')
    }
  },

并在 .update 调用者上抛出。

但请记住来自why sequelize beforeUpdate hook doesn't work?如果调用者使用:

Model.update({}, {individualHooks: true})

每次都要记住 pass 会很烦人。

beforeValidate 钩子(Hook)即使没有 individualHooks 也会触发,所以也许这就是方法。

关于 create throw 有效的事实记录在:https://sequelize.org/master/manual/hooks.html#instance-hooks

User.beforeCreate(user => {
  if (user.accessLevel > 10 && user.username !== "Boss") {
    throw new Error("You can't grant this user an access level above 10!");
  }
});

The following example will throw an error:

try {
  await User.create({ username: 'Not a Boss', accessLevel: 20 });
} catch (error) {
  console.log(error); // You can't grant this user an access level above 10!
};

The following example will be successful:

const user = await User.create({ username: 'Boss', accessLevel: 20 });
console.log(user); // user object with username 'Boss' and accessLevel of 20

还提到:https://github.com/sequelize/sequelize/issues/11298

最小可运行示例:

主要.js

#!/usr/bin/env node
const assert = require('assert')
const path = require('path')
const { DataTypes, Sequelize } = require('sequelize')
let sequelize
if (process.argv[2] === 'p') {
  sequelize = new Sequelize('tmp', undefined, undefined, {
    dialect: 'postgres',
    host: '/var/run/postgresql',
  })
} else {
  sequelize = new Sequelize({
    dialect: 'sqlite',
    storage: 'tmp.sqlite',
  })
}
function assertEqual(rows, rowsExpect) {
  assert.strictEqual(rows.length, rowsExpect.length)
  for (let i = 0; i < rows.length; i++) {
    let row = rows[i]
    let rowExpect = rowsExpect[i]
    for (let key in rowExpect) {
      assert.strictEqual(row[key], rowExpect[key])
    }
  }
}
;(async () => {
const IntegerNames = sequelize.define('IntegerNames',
  {
    value: { type: DataTypes.INTEGER },
    name: { type: DataTypes.STRING },
  },
  {
    hooks: {
      beforeCreate: (integerName, options) => {
        if (integerName.value === 42) {
          throw new Error('beforeCreate')
        }
      },
      beforeValidate: (integerName, options) => {
        if (integerName.value === 43) {
          throw new Error('beforeValidate')
        }
      },
      beforeUpdate: (integerName, options) => {
        if (integerName.value === 5) {
          throw new Error('beforeUpdate')
        }
      },
    }
  },
)
await IntegerNames.sync({ force: true })
async function reset() {
  await sequelize.truncate({ cascade: true })
  await IntegerNames.create({ value: 2, name: 'two' })
  await IntegerNames.create({ value: 3, name: 'three' })
  await IntegerNames.create({ value: 5, name: 'five' })
}
async function assertUnchanged() {
  const rows = await IntegerNames.findAll()
  assertEqual(rows, [
    { id: 1, value: 2, name: 'two',   },
    { id: 2, value: 3, name: 'three', },
    { id: 3, value: 5, name: 'five',  },
  ])
}
await reset()
let rows, exc
await assertUnchanged()

// beforeCreate
exc = undefined
try {
  await IntegerNames.create({ value: 42, name: 'forty-two' })
} catch (e) {
  exc = e
}
assert.strictEqual(exc.message, 'beforeCreate')
await assertUnchanged()

// beforeValidate
exc = undefined
try {
  await IntegerNames.create({ value: 43, name: 'forty-three' })
} catch (e) {
  exc = e
}
assert.strictEqual(exc.message, 'beforeValidate')
await assertUnchanged()

// beforeUpdate
exc = undefined
try {
  await IntegerNames.update(
    { name: 'five hacked', },
    {
      where: { value: 5 },
      individualHooks: true,
    },
  );
} catch (e) {
  exc = e
}
assert.strictEqual(exc.message, 'beforeUpdate')
await assertUnchanged()

// using the beforeValidate
exc = undefined
try {
  await IntegerNames.update(
    { value: 43, },
    {
      where: { value: 5 },
    },
  );
} catch (e) {
  exc = e
}
assert.strictEqual(exc.message, 'beforeValidate')
await assertUnchanged()
})().finally(() => { return sequelize.close() })

包.json

{
  "name": "tmp",
  "private": true,
  "version": "1.0.0",
  "dependencies": {
    "pg": "8.5.1",
    "pg-hstore": "2.3.3",
    "sequelize": "6.14.0",
    "sql-formatter": "4.0.2",
    "sqlite3": "5.0.2"
  }
}

GitHub upstream .在 Ubuntu 21.10、PostgreSQL 13.5 上测试。

关于node.js - 如何使用 beforeUpdate Hook Sequelize 中止更新操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64362298/

相关文章:

javascript - WebStorm 找不到导出函数的用法

sequelize.js - sequelize.sync() 如何工作,特别是强制选项?

postgresql - Sequelize – 按值存在排序

node.js - sequelize - 如何为日期字段设置验证规则

javascript - 如何流式传输 blob

node.js - 为 MongoDB 中的对象数组建立索引

mysql - Sequelize 使用 MySQL 抛出断言错误

javascript - 如何打破从内部 promise 函数触发的循环?

node.js - Node js + socket io 仍然在客户端显示错误,如何修复? CentOS7

javascript - 无法读取未定义的属性 'currentUser'