【问题标题】:Sequelize: calculate values before creating AND updatingSequelize:在创建和更新之前计算值
【发布时间】:2016-03-15 22:25:56
【问题描述】:

我的问题类似于Sequelize calculate value before saving,但不完全相同。

我还有一个模型,其中一个字段将被设置,另一个字段永远不会设置,但应在每次保存到数据库操作之前计算。我试图通过使用钩子来实现这一点。

var Foo = sequelize.define(
  'foo',
  {
     bar: { type: Sequelize.TEXT, allowNull: false },
     baz: { type: Sequelize.TEXT, allowNull: false }
  },
  {
    freezeTableName: true,
    timestamps: false,
    hooks: {
        // beforeCreate: setBaz
        // beforeUpdate: setBaz
        beforeValidate: setBaz
    }
  }
);

function setBaz(foo) {
  foo.baz = foo.bar + "_baz";
}

这适用于创建但不适用于更新现有元素。

Foo.create({bar: "bar"});

correclty 创建以下语句

INSERT INTO "foo" ("id","bar","baz") VALUES (DEFAULT,'bar','bar_baz') RETURNING *;

然而,

Foo.findOne({where: {id: 1}})
  .then(function(foo) {
    return foo.update({bar: "foobar"});
  });

这些陈述的结果

SELECT "id", "bar", "baz" FROM "foo" AS "foo" WHERE "foo"."id" = 1;    
UPDATE "foo" SET "bar"='foobar' WHERE "id" = 1

显然只为 bar 设置新值。

当像这样记录更改时

function setBaz(foo) {
  console.log(foo);
  foo.baz = foo.bar + "_baz";
  console.log(foo);
}

可以看到函数执行完毕,值设置正确。 之前:

dataValues: { id: 1, bar: 'foobar', baz: 'bar_baz' },
_previousDataValues: { id: 1, bar: 'bar', baz: 'bar_baz' },
_changed: { bar: true },

之后:

dataValues: { id: 1, bar: 'foobar', baz: 'foobar_baz' },
_previousDataValues: { id: 1, bar: 'bar', baz: 'bar_baz' },
_changed: { bar: true, baz: true },

更改的标志也设置正确。

我之前尝试过使用 beforeCreatebeforeUpdate 挂钩,但这会导致创建案例出错,这似乎是合理的。

Unhandled rejection SequelizeValidationError: notNull Violation: baz cannot be null

使用 get/setDataValue 也不会改变任何事情

foo.setDataValue("baz", foo.getDataValue("bar") + "_baz");

钩子上的文档非常少,因此非常感谢任何帮助。如何让 sequelize 也更新计算字段?

【问题讨论】:

  • 返回 Promise 和/或调用回调也无济于事。

标签: node.js sequelize.js


【解决方案1】:

似乎 sequelize 在调用验证钩子之前计算更改的字段。为了覆盖它,您可以更改传递的选项中的字段

function setBaz(foo, o) {
  if(_.contains(o.fields, "bar")) { // if bar was not changed, nothing has to be done
    foo.setDataValue("baz", foo.getDataValue("bar") + "_baz");

    if(!_.contains(o.fields, "baz")) {
      o.fields.push("baz");  // Adjust the fields to be saved
      _.pull(o.skip, "baz"); // Also adjust the skipped fields, for consistency
    }
  }
  return Promise.resolve(o);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-13
    • 2013-08-20
    • 2019-09-02
    • 2019-03-31
    • 1970-01-01
    • 2015-12-11
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多