实例 Hook

当你编辑单个对象时,以下 hook 将触发

  1. beforeValidate
  2. afterValidate or validationFailed
  3. beforeCreate / beforeUpdate / beforeSave / beforeDestroy
  4. afterCreate / afterUpdate / afterSave / afterDestroy
  1. // ...定义 ...
  2. User.beforeCreate(user => {
  3. if (user.accessLevel > 10 && user.username !== "Boss") {
  4. throw new Error("你不能授予该用户10级以上的访问级别!")
  5. }
  6. })

此示例将返回错误:

  1. User.create({username: 'Not a Boss', accessLevel: 20}).catch(err => {
  2. console.log(err); // 你不能授予该用户 10 级以上的访问级别!
  3. });

以下示例将返回成功:

  1. User.create({username: 'Boss', accessLevel: 20}).then(user => {
  2. console.log(user); // 用户名为 Boss 和 accessLevel 为 20 的用户对象
  3. });

模型 Hook

有时,你将一次编辑多个记录,方法是使用模型上的 bulkCreate, update, destroy 方法. 当你使用以下方法之一时,将会触发以下内容:

  1. beforeBulkCreate(instances, options)
  2. beforeBulkUpdate(options)
  3. beforeBulkDestroy(options)
  4. afterBulkCreate(instances, options)
  5. afterBulkUpdate(options)
  6. afterBulkDestroy(options)

如果要为每个单独的记录触发 hook,连同批量 hook,你可以将 personalHooks:true 传递给调用.

警告: 如果你使用单独的 hook,在你的hook被调用之前,所有被更新或销毁的实例都会被加载到内存中. Sequelize可以处理各个 hook 的实例数量受可用内存的限制.

  1. Model.destroy({ where: {accessLevel: 0}, individualHooks: true});
  2. // 将选择要删除的所有记录,并在每个实例删除之前 + 之后触发
  3. Model.update({username: 'Toni'}, { where: {accessLevel: 0}, individualHooks: true});
  4. // 将选择要更新的所有记录,并在每个实例更新之前 + 之后触发

Hook 方法的 options 参数将是提供给相应方法或其克隆和扩展版本的第二个参数.

  1. Model.beforeBulkCreate((records, {fields}) => {
  2. // records = 第一个参数发送到 .bulkCreate
  3. // fields = 第二个参数字段之一发送到 .bulkCreate
  4. })
  5. Model.bulkCreate([
  6. {username: 'Toni'}, // 部分记录参数
  7. {username: 'Tobi'} // 部分记录参数
  8. ], {fields: ['username']} // 选项参数
  9. )
  10. Model.beforeBulkUpdate(({attributes, where}) => {
  11. // where - 第二个参数的克隆的字段之一发送到 .update
  12. // attributes - .update 的第二个参数的克隆的字段之一被用于扩展
  13. })
  14. Model.update({gender: 'Male'} /*属性参数*/, { where: {username: 'Tom'}} /*where 参数*/)
  15. Model.beforeBulkDestroy(({where, individualHooks}) => {
  16. // individualHooks - 第二个参数被扩展的克隆被覆盖的默认值发送到 Model.destroy
  17. // where - 第二个参数的克隆的字段之一发送到 Model.destroy
  18. })
  19. Model.destroy({ where: {username: 'Tom'}} /*where 参数*/)

如果用 updates.OnDuplicate 参数使用 Model.bulkCreate(...) ,那么 hook 中对 updateOnDuplicate 数组中没有给出的字段所做的更改将不会被持久保留到数据库. 但是,如果这是你想要的,则可以更改 hook 中的 updateOnDuplicate 选项.

  1. // 使用 updatesOnDuplicate 选项批量更新现有用户
  2. Users.bulkCreate([
  3. { id: 1, isMember: true },
  4. { id: 2, isMember: false }
  5. ], {
  6. updateOnDuplicate: ['isMember']
  7. });
  8. User.beforeBulkCreate((users, options) => {
  9. for (const user of users) {
  10. if (user.isMember) {
  11. user.memberSince = new Date();
  12. }
  13. }
  14. // 添加 memberSince 到 updateOnDuplicate 否则 memberSince 期将不会被保存到数据库
  15. options.updateOnDuplicate.push('memberSince');
  16. });