2016-11-20 103 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,然後將其解析爲對象才能呈現,這實際上是浪費週期。