【问题标题】:sequelize beforeCreate hook is not executingsequelize beforeCreate 挂钩未执行
【发布时间】:2020-10-07 22:47:39
【问题描述】:

我在我的 sequelize 模型中编写了一个 BeforeCreate 钩子。当我点击创建用户路由时,它说 user.user_id 不能为空,甚至在创建钩子函数未执行之前。我遵循了 sequelize 的文档。他们提到的和我使用的一样。我在我的 sequelize 模型中编写了一个 BeforeCreate 钩子。当我点击创建用户路由时,它说 user.user_id 不能为空,甚至在创建钩子函数未执行之前。我遵循了 sequelize 的文档。他们提到的和我使用的一样。

const sequelize = require("kvell-db-plugin-sequelize").dbInstance;
const Sequelize = require("kvell-db-plugin-sequelize").dbLib;
const shortid = require("shortid");
const User = sequelize.define(
  "user",
  {
    id: {
      type: Sequelize.INTEGER,
      autoIncrement: true,
      allowNull: false
    },
    user_id: {
      type: Sequelize.STRING,
      allowNull: false,
      primaryKey: true,
      unique: true
    },
    user_fname: {
      type: Sequelize.STRING,
      allowNull: false
    },
    user_lname: {
      type: Sequelize.STRING,
      allowNull: false
    },
    user_fullName: {
      type: Sequelize.VIRTUAL,
      get() {
        return `${this.user_fname} ${this.user_lname}`;
      },
      set(value) {
        throw new Error("Do not try to set the `fullName` value!");
      }
    },
    user_email: {
      type: Sequelize.STRING,
      allowNull: false,
      primaryKey: true,
      validate: {
        isEmail: true
      },

      unique: {
        args: true,
        msg: "Email address already in use!"
      }
    },
    user_credential: {
      type: Sequelize.STRING,
      allowNull: false
    },
    user_roles: {
      type: Sequelize.ARRAY(Sequelize.STRING),
      allowNull: false,
      defaultValue: ["Admin"]
    },
    admin: {
      type: Sequelize.BOOLEAN,
      allowNull: false,
      defaultValue: true
    },
    user_img: {
      type: Sequelize.STRING,
      allowNull: true
    }
  },
  {
    timestamps: true

 }
);

User.beforeCreate(async (user, options) => {
  console.log("inside hooks");
  let id = `user_${shortid.generate()}`;
  user.user_id = id;
});

const toJSON = User.prototype.toJSON;

User.prototype.toJSON = function({ attributes = [] } = {}) {
  const obj = toJSON.call(this);

  if (!attributes.length) {
    return obj;
  }

  return attributes.reduce((result, attribute) => {
    result[attribute] = obj[attribute];

    return result;
  }, {});
};

module.exports = User;

【问题讨论】:

    标签: node.js sequelize.js


    【解决方案1】:

    真正的答案(在其中一个 cmets 中暗示但未明确说明)是 beforeCreate 钩子在模型验证之后应用

    这意味着如果您的模型中有任何字段(例如 id )不能为空,Sequelize 将在应用 beforeCreate 字段之前对其进行评估。在您的情况下,Sequelize 永远不会到达 beforeCreate 挂钩,因为 null id 每次都无法通过验证。

    您接受的答案通过设置allowNull = true 解决了这个问题,从而绕过了对您的(简要)空id 的验证。但更好的选择(而不是通过允许 null id 来扭曲您的模型)几乎肯定是使用正确的钩子:beforeValidate。此挂钩在评估模型标准之前应用。

    这是一个非常简单的改变:

    User.beforeValidate(async (user, options) => {
      console.log("inside hooks");
      let id = `user_${shortid.generate()}`;
      user.user_id = id;
    });
    

    注意:async 在这里是多余的。

    【讨论】:

      【解决方案2】:
       user_id: {
            type: Sequelize.STRING,
            allowNull: false,
            primaryKey: true,
            unique: true
          }
      

      在本节中,我设置了 user_id allowNull = false beforeCreate 在 beforeValidate 钩子之后执行。但是在 beforeValidate 钩子中,它抛出了 user.user_id===null 的错误原因,所以我允许 allowNull===true,现在它正在工作。

      【讨论】:

      【解决方案3】:

      尝试在这段代码中删除 async

      async (user, options)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 2015-08-31
        • 2014-05-13
        • 2021-09-10
        相关资源
        最近更新 更多