【发布时间】: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 },
更改的标志也设置正确。
我之前尝试过使用 beforeCreate 和 beforeUpdate 挂钩,但这会导致创建案例出错,这似乎是合理的。
Unhandled rejection SequelizeValidationError: notNull Violation: baz cannot be null
使用 get/setDataValue 也不会改变任何事情
foo.setDataValue("baz", foo.getDataValue("bar") + "_baz");
钩子上的文档非常少,因此非常感谢任何帮助。如何让 sequelize 也更新计算字段?
【问题讨论】:
-
返回 Promise 和/或调用回调也无济于事。
标签: node.js sequelize.js