Reputation: 508
I have two models: User and Images. User has profile_image_id
column.
When i get the user with include {model:Images, as:'profileImage', attributes:['filename']}
I get profileImage
as object with filename
as property.
Is there a way in Sequelize to get that 'filename' as a property of User model? Meaning to execute
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
What works for now is defining VIRTUAL
attribute profileImageFIlename
on user and then populating it in afterFind
function of User model. But it seems like a lot of extra work and unnecessary data.
Is there a better way except raw query?
Upvotes: 1
Views: 8584
Reputation: 27599
The short answer is that there isn't a way to do it that would be "less work". Even in your example SQL query you reference i.filename
using the alias that you created for the related images
table. This effectively maps to User.images.filename
, which is just as usable as User.profile_image_file
.
If you would like profile_image_id
to exist as a VIRTUAL
field on User
then you are doing it the correct way - VIRTUAL
fields won't be persisted to the database schema, so you would need to set them from some other source. In this case, the related images
table provides the value and you will need to set it in the afterfind()
hook.
If you don't care about it being on the User
Instance
or Model
and just want to access the value in the results without having to traverse the object, you can use something like the following to alias the column by leveraging 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);
});
This will result in SQL of
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;
Upvotes: 7