【问题标题】:Sequelize create model with beforeCreate hook使用 beforeCreate 钩子继续创建模型
【发布时间】:2015-10-04 07:49:54
【问题描述】:

我在 beforeCreate 之前定义了我的钩子如下:

module.exports = function (sequelize, DataTypes) {
  var userSchema = sequelize.define('User', {
  // define...
  });
  userSchema.beforeCreate(function (model) {
    debug('Info: ' + 'Storing the password');    
    model.generateHash(model.password, function (err, encrypted) {
      debug('Info: ' + 'getting ' + encrypted);

      model.password = encrypted;
      debug('Info: ' + 'password now is: ' + model.password);
      // done;
    });
  });
};

当我创建模型时

  User.create({
    name:           req.body.name.trim(),
    email:          req.body.email.toLowerCase(),
    password:       req.body.password,
    verifyToken:    verifyToken,
    verified:       verified
  }).then(function (user) {
    debug('Info: ' + 'after, the password is ' + user.password);    
  }).catch(function (err) {
    // catch something
  });

现在我从中得到的是

Info: Storing the password +6ms
Info: hashing password 123123 +0ms    // debug info calling generateHash()
Executing (default): INSERT INTO "Users" ("id","email","password","name","verified","verifyToken","updatedAt","createdAt") VALUES (DEFAULT,'wwx@test.com','123123','wwx',true,NULL,'2015-07-15 09:55:59.537 +00:00','2015-07-15 09:55:59.537 +00:00') RETURNING *;

Info: getting $2a$10$6jJMvvevCvRDp5E7wK9MNuSRKjFpieGnO2WrETMFBKXm9p4Tz6VC. +0ms
Info: password now is: $2a$10$6jJMvvevCvRDp5E7wK9MNuSRKjFpieGnO2WrETMFBKXm9p4Tz6VC. +0ms
Info: after, the password is 123123 +3ms

似乎代码的每个部分都在工作。创建用户模式将调用 beforeCreate,它会正确生成密码的哈希码.... 除了它没有写入数据库!

我确定我遗漏了一段非常重要且显而易见的代码,但我就是找不到问题所在(啊哈)。任何帮助表示赞赏!

【问题讨论】:

    标签: node.js sequelize.js


    【解决方案1】:

    Sequelize 中以异步方式调用 Hook,因此您需要在完成后调用完成回调:

    userSchema.beforeCreate(function(model, options, cb) {
      debug('Info: ' + 'Storing the password');    
      model.generateHash(model.password, function(err, encrypted) {
        if (err) return cb(err);
        debug('Info: ' + 'getting ' + encrypted);
    
        model.password = encrypted;
        debug('Info: ' + 'password now is: ' + model.password);
        return cb(null, options);
      });
    });
    

    (或者,您可以从钩子中返回一个承诺)

    【讨论】:

    • @user2242178 别担心,很高兴听到它解决了您的问题 :-)
    • 谢谢。我在 sequelize 文档中没有看到这一点,它阻止了我的服务器响应。
    • @Danielo515 是的,它的记录不是很清楚:-(
    • 更新版sequlize没有回调函数
    • @AryehArmon 返回一个承诺。
    【解决方案2】:

    对于较新版本的 Sequelize,钩子不再具有回调函数,而是承诺。因此,代码看起来更像如下:

    userSchema.beforeCreate(function(model, options) {
        debug('Info: ' + 'Storing the password');
    
        return new Promise ((resolve, reject) => {
            model.generateHash(model.password, function(err, encrypted) {
                if (err) return reject(err);
                debug('Info: ' + 'getting ' + encrypted);
    
                model.password = encrypted;
                debug('Info: ' + 'password now is: ' + model.password);
                return resolve(model, options);
            });
        });
    });
    

    【讨论】:

    • sequelize 是否支持模型挂钩中的 async/await 函数?
    • Async/await 函数还没有在 node 中实现,所以当你编写 Async/Await 时,它会被 Babel 转译回 Promise
    • 我以为 async/await 是随节点 8 发布的 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 我的项目中没有使用 babel,我的代码使用 async/await 函数编译。你能解释一下吗?
    • 哦,我猜你是对的,但是发行说明说 async await 使用了 Promise,所以它应该还是可以的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 2012-04-06
    相关资源
    最近更新 更多