I have a table Relation with columns userId1 and userId2 it basically stores the relation between two users, userId1 and userId2 is foreign key here referenced from the User tables id (PK) column.
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
userId1: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
},
userId2: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
},
status: {
type: DataTypes.ENUM,
},
Then there is another table Posts containing information about posts.
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
content: {
type: DataTypes.TEXT,
allowNull: false,
},
postedBy: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
},
I want to get lists of post of only those user who have a relation with me like friends , means my id lets suppose is 1 and it is in userId1 column and userId2 column has id in it, then I want to fetch all posts of value 2 from posts postedBy column. This case can be vice versa as my id can be in userId2 column and I need to get all posts of the user whose value is in userId1 column.
I have read through all the questions and answers like multiple associations but it is just not working for me.
This is my associations in Posts model
Posts.hasOne(RelationModel, {
foreignKey: 'userId1',
sourceKey: 'postedBy',
as: 'first',
})
Posts.hasOne(RelationModel, {
foreignKey: 'userId2',
sourceKey: 'postedBy',
as: 'second',
})
Below is my include array.
include:[
{
model: RelationModel,
as: 'first',
where: {
status: 'accepted',
[Op.or]: [
{ userId1: request.user.id },
{ userId2: request.user.id },
],
},
},
{
model: RelationModel,
as: 'second',
where: {
status: 'accepted',
[Op.or]: [
{ userId1: request.user.id },
{ userId2: request.user.id },
],
},
}
]
The query being generated from this is below, where 151 is the logged in user id, means my id
SELECT
`posts`.*,
`first`.*,
`second`.*
FROM
`posts` AS `posts`
INNER JOIN
`relations` AS `first` ON `posts`.`postedBy` = `first`.`userId1`
AND (`first`.`userId1` = 151
OR `first`.`userId2` = 151)
AND `first`.`status` = 'accepted'
INNER JOIN
`relations` AS `second` ON `posts`.`postedBy` = `second`.`userId2`
AND (`second`.`userId1` = 151
OR `second`.`userId2` = 151)
AND `second`.`status` = 'accepted'
WHERE
`posts`.`deletedAt` IS NULL
ORDER BY `posts`.`id` ASC , `posts`.`id` ASC;
But the query I want to build is below
SELECT
`posts`.*,
`first`.*
FROM
`posts` AS `posts`
INNER JOIN
`relations` AS `first` ON (`posts`.`postedBy` = `first`.`userId2`
OR `posts`.`postedBy` = `first`.`userId1`)
AND (`first`.`userId1` = 151
OR `first`.`userId2` = 151)
AND `first`.`isFriend` = TRUE
AND `first`.`status` = 'accepted'
WHERE
`posts`.`deletedAt` IS NULL
ORDER BY `posts`.`id` ASC , `posts`.`id` ASC;
How to construct this query in sequelize?
You need to specify a unique as
keyword for each relationship in the association as well as on the include
for your query.
Posts.hasOne(RelationModel, {
foreignKey: 'userId1',
sourceKey: 'postedBy',
as: 'first',
});
Posts.hasOne(RelationModel, {
foreignKey: 'userId2',
sourceKey: 'postedBy',
as: 'second',
});
Then when you query you specify the unique as
that identifies the relationship for the join
Post.findByPk(id, {
include: [{
model: RelationModel,
as: 'first',
},
{
model: RelationModel,
as: 'second',
}],
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.