2016-11-20 110 views
0

我已经耗尽了我在这里和其他地方找到的所有内容。看起来其他人正在取得成功,但我所做的任何事情都不会让我看到任何虚拟领域。我已经尝试了作为领域和getterMethods无济于事。我确定我的项目中安装了最新的Sequelize版本。无法让虚拟字段在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'}) 
    } 
} 

由于所报,它试图使用属性定义与虚拟类型。我也试过只是虚拟,没有其他类型或依赖关系。为了测试,我还对示例返回值进行了硬编码。

使用getterMethods(注释掉)票价的替代方案不会更好。根据我所能找到的一切,我应该能够执行find(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) 
    }); 
}; 

有没有错误,如预期检索的项目,一切完美*除了虚拟领域。他们根本不在那里被发现。请求原始或完整对象没有区别。

+0

似乎为我工作,你也可以粘贴你的检索代码? – drinchev

+1

向原始文章添加检索代码 - 似乎无法在评论中很好地格式化它。 –

+0

挖掘整个返回的对象(关闭原始数据)我在以下位置找到对我的虚拟字段的引用: orderlines [0] .__ proto__ 在此属性属性是一个包含我的虚拟字段的名称数组,是每个属性的字段 - 所有都是未定义的*除了我的虚拟字段的值,我的硬编码值分别高于 - 199.95和45。 原始设置为true,这不会通过。测试更多我也看到这些将保持未定义,如果作为他们需要的两个其他领域的产品。 –

回答

0

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

问题是您检索结果的方式。通过在查询中使用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选项。

+0

感谢您的帮助。原始选项的文档没有提到不允许虚拟字段的工作,所以我不知道应该如何知道这一点。 所以要获得虚拟属性我*不能*使用原始的,我必须*转换为JSON?似乎两者,特别是不能使用原始的,可能会损害性能。 –

+0

表现会受到伤害。你是对的。那么你根本不能使用虚拟化,只需设法用你想要的任何值来丰富你的“原始”对象。'raw'选项不会实例化你的结果,所以它不会考虑虚拟,而是类型等。你基本上会绕过你的ORM中的所有逻辑,这很快 - 是的,但是为什么你需要一个ORM在第一位。 – drinchev

+0

第一:现在正在工作。谢谢。 应用程序正在呈现服务器端,对象不会被发送到或在客户端操纵。因此,为此目的不需要完整的对象。在服务器端,raw不是真正的问题,所以需要它来获得虚拟表和其他好东西实际上并不是问题。但是,必须转换为JSON,然后将其解析为对象才能呈现,这实际上是浪费周期。