2016-12-07 88 views
0

我有兩個模型:User和Images。用戶有profile_image_id列。Sequelize - 從關聯表中返回單列作爲自定義列

當我得到用戶include {model:Images, as:'profileImage', attributes:['filename']}我得到profileImage作爲對象與filename作爲屬性。

在Sequelize中有一種方法可以將'filename'作爲User模型的屬性嗎? 含義執行

SELECT u.id, u.name, i.filename 
FROM users u 
LEFT JOIN images i ON i.id = u.profile_image_id 
WHERE u.id = 1 

現在是定義用戶VIRTUAL屬性profileImageFIlename,然後在用戶模式afterFind功能填充它的作品。但它似乎有很多額外的工作和不必要的數據。

除原始查詢外還有更好的方法嗎?

回答

1

簡短的回答是,沒有一種方法可以做到「少工作」。即使在您的示例SQL查詢中,也可以使用您爲相關的images表創建的別名引用i.filename。這有效地映射到User.images.filename,這與User.profile_image_file一樣可用。

如果您想profile_image_id作爲一個VIRTUAL場存在於User那麼你正在做正確的方式 - VIRTUAL字段將不會被持久化到數據庫模式,所以你需要從其他來源進行設置。在這種情況下,相關的images表提供了該值,您需要將其設置在afterfind()鉤子中。

如果你不關心它是在UserInstanceModel,只是希望在不必遍歷對象訪問結果的值,你可以使用類似下面通過利用Sequelize.literal()別名列。

User.findById(1, { 
    attributes: { 
    include: [[Sequelize.literal('images.filename'), 'profile_image_file']], 
    }, 
    include: [{ model: Images, as: 'images', attributes: [] }] 
}) 
.then((user) => { 
    // There will be a user.dataValues.profile_image_file value populated 
    // but not a user.profile_image_file unless you set it in afterFind() 
    console.log(user.dataValues); 
}); 

這將導致SQL

SELECT `user`.`id`, `user`.`name`, images.filename AS `profile_image_file` 
FROM `user` AS `user` 
LEFT OUTER JOIN `images` AS `images` ON `user`.`profile_image_id` = `images`.`id` 
WHERE `user`.`id` = 1;