无法使Sequelize中的虚拟字段工作

时间:2016-11-20 03:12:25

标签: sequelize.js

我已经把我在这里和其他地方找到的所有东西都用尽了。似乎其他人取得了成功,但我所做的一切都不会让我看到任何虚拟领域。我已经尝试过两个字段和getterMethods无济于事。我确保在我的项目中安装了最新的Sequelize版本。

这是对象定义:

var Orderitem = sequelize.define("Orderitem", {
    description: { type: DataTypes.STRING(80), allowNull: false },
    quantity: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0},
    unitWeight: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0},
    price: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0},

    totalPrice: { 
      type: DataTypes.VIRTUAL(DataTypes.DECIMAL(9,2), ['price', 'quantity']),
      get() {
        //return this.getDataValue('unitWeight') * this.getDataValue('quantity');
        return 195.99;
      }
    }, 
    totalWeight: { 
      type:  DataTypes.VIRTUAL(DataTypes.DECIMAL(9,2), ['unitWeight', 'quantity']),
      get() {
        //return this.getDataValue('unitWeight') * this.getDataValue('quantity');
        return 45;
      }
    },
  }, {
/*
    getterMethods: {
      testFoo: function () {
          return 'Foo';
      },
      totalPrice: function () { 
        return  this.getDataValue('price') * this.getDataValue('quantity');
      },
      totalWeight: function() {
        return this.getDataValue('unitWeight') * this.getDataValue('quantity');
      }
    },
*/
    classMethods: {
      associate: function(models) {
        Orderitem.belongsTo(models.Order, {onDelete: 'CASCADE'})
    }
}

引用时,它试图使用VIRTUAL类型的属性定义。我也试过只是虚拟,没有其他类型或依赖。为了测试,我还硬编码了样本返回值。

使用getterMethods(在这里注释掉)的替代方案不会更好。

根据我能找到的所有内容,我应该能够执行查找(findOne,findAll等),这些应该作为字段以及所有其他字段返回。前4个字段从数据库返回预期值。无处可寻找虚拟字段。使用上面的任何一种方法,我做错了什么?

检索代码是:

OrderController.items = function (orderId, callback) {
    models.Orderitem.findAll({
        //attributes: Object.keys(models.Orderitem.attributes).concat([ 'totalPrice','totalWeight']),
        where: {orderId: orderId}, raw: true
    }).then(function(orderitems) {
        callback(null, orderitems)
    }).catch(function(error) {
        callback(error, null)
    });
 };

没有错误,按预期检索项目,除虚拟字段外,一切都完美无缺。它们根本就没有被发现。请求原始或完整对象没有区别。

2 个答案:

答案 0 :(得分:1)

虚拟按照定义的方式工作。

问题在于您检索结果的方式。通过在查询中使用raw选项,Sequelize假定您不想创建DAO,因此它不会评估虚拟,也不会自己创建实例。

OrderController.items = function (orderId, callback) {
    models.Orderitem.findAll({    
        where: {orderId: orderId} // commenting out `raw: true`
    }).then(function(orderitems) {   
        if ( orderitems.length > 0 ) { 
            console.log(orderitems[0].totalPrice);
        };
        callback(null, orderitems)
    }).catch(function(error) {
        callback(error, null)
    });
 };

您可以在Sequelize Documentation中详细了解raw选项。

答案 1 :(得分:1)

执行查找操作(findOne、findAll 等)后,您必须显式访问这些 virtual fields

例如

await models.Orderitem.findAll({
  where: { orderId: orderId },
}).then((orderitems) =>
  orderitems.map((orderitem) => {
    console.log('orderitem:', orderitem);
    console.log('totalPrice (virtual field): ', orderitem.totalPrice);
  })
);

仔细观察,console.log('orderitem:', orderitem) 不打印 totalPrice,但 totalPrice 位于此处,返回其在 console.log('totalPrice (virtual field): ', orderitem.totalPrice) 中看到的值。

这是一个 getter 值,您必须访问该值,当您访问它时,Javascript 会在运行时生成值。