I want to retrieve users post by users logged in Id with following conditions. As currently I am getting user-post as null.
1: If user posted a post. same user should be able to view his post (if same user is not friend with anyone i.e ACCEPTED status).
2: If user posted a post, other users with whom he is friend should be able to view post.
Basically I have used following database design,
1: Users id, first Name, last Name
2: Post id, post
3: UserPost id, postId, (referencing Post table), userId (referencing User table)
4: Friendship id, userId, (referencing User table) friendUserId, (referencing User table) friendshipStatus (e.g values ACCEPTED, REJECTED)
Following is associations and query to retrieve the records schema,
1: User association
const Users = sequelize.define(
'Users',
{
id: {
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'id'
},
firstName: {
type: DataTypes.STRING(20),
allowNull: true,
field: 'firstName'
},
lastName: {
type: DataTypes.STRING(20),
allowNull: true,
field: 'lastName'
},
{
tableName: 'users'
}
);
Users.associate = models => {
Users.hasMany(models.Friendships, { foreignKey: 'userId', as: 'friendship'});
Users.hasMany(models.UserPost, { foreignKey: 'userId', as: 'user-post'
});
}
2: Friendship association
const Friendships = sequelize.define(
'Friendships',
{
id: {
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'id'
},
userId: {
type: DataTypes.BIGINT,
allowNull: false,
references: {
model: 'users',
key: 'id'
},
field: 'userId'
},
friendUserId: {
type: DataTypes.BIGINT,
allowNull: false,
references: {
model: 'users',
key: 'id'
},
field: 'friendUserId'
},
friendshipStartDate: {
type: DataTypes.DATE,
allowNull: true,
field: 'friendshipStartDate'
},
friendshipStatusId: {
type: DataTypes.STRING(20),
allowNull: true,
field: 'friendshipStatusId'
},
},
{
tableName: 'friendships'
}
);
Friendships.associate = models => {
Friendships.belongsTo(models.UserPost, { foreignKey: 'userId', as: 'user-post' });
Friendships.belongsTo(models.Users, { foreignKey: 'id', as: 'user' });
};
3: Post association
const Post = sequelize.define(
'Post',
{
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'id'
},
post: {
type: DataTypes.STRING(1000),
allowNull: false,
// defaultValue: '0',
field: 'Post'
},
postStatusId: {
type: DataTypes.INTEGER(10),
allowNull: true,
field: 'PostStatusId'
},
createdBy: {
type: DataTypes.INTEGER(10),
allowNull: true,
field: 'CreatedBy'
},
updatedBy: {
type: DataTypes.INTEGER(10),
allowNull: true,
field: 'ModifiedBy'
}
},
{
tableName: 'posts',
updatedAt: false,
createdAt: false
}
);
Post.associate = models => {
Post.belongsTo(models.Friendships, { foreignKey:'userId', as: 'friendship' });
Post.belongsTo(models.UserPost, { foreignKey: 'postId', as: 'userspost' });
Post.belongsTo(models.Users, { foreignKey: 'id', as: 'user' });
};
4: UserPost association
const UserPost = sequelize.define(
'UserPost',
{
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'id'
},
userId: {
type: DataTypes.STRING(1000),
allowNull: false,
references: {
model: 'user',
key: 'id'
},
field: 'userId'
},
postId: {
type: DataTypes.INTEGER(10),
allowNull: true,
references: {
model: 'posts',
key: 'id'
},
field: 'postId'
}
},
{
tableName: 'user_posts',
updatedAt: false,
createdAt: false
}
);
UserPost.associate = models => {
UserPost.hasMany(models.Post, { sourceKey:'postId', foreignKey: 'id', as: 'post' });
UserPost.hasMany(models.Friendships, { foreignKey:'userId', as: 'friend'
});
};
序列化查询 const result = await Users.findAll({
attributes: ['id', 'firstName', 'lastName'],
subQuery: false,
include: [
{
model: Friendships,
as: 'friendship',
attributes: ['userId', 'friendUserId'],
where:
{
[Op.or]: {
userId: userId,
friendUserId: userId
},
[Op.and]: {
friendshipStatusId: 'ACCEPT'
}
},
include: [{
model: UserPost,
as: 'user-post',
attributes: ['userId', 'postId'],
subQuery: false,
include: [
{
model: Post,
as: 'post',
attributes:['id','post'],
}
],
}]
}
] })
But in this query I am not getting users post records since there is one entry in database of user post. following is actual result for above query.
响应
[
{
"id": 5,
"firstName": "Abc",
"lastName": "Xyz",
"friendship": [
{
"userId": 5,
"friendUserId": 6,
"user-post": null
}
]
}
]
do anyone having solution for this?
最佳答案
只是为了确保我们在同一页面上,从功能的 Angular 来看,您希望用户能够彼此成为 friend ,并且用户创建的帖子只能由该用户和他的 friend 看到。
从 UserPost 的关系 Angular 来看,您希望获得所有有权访问帖子的用户。
如果这是正确的,那么实现它的方法就简单得多。
首先,您不需要用户和帖子(UserPost)之间的多对多关系,因为除非帖子可以有多个创建者,否则您不需要很多用户属于一个帖子。
从原始数据库表的 Angular 来看,我们想要(最小):
用户:
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| firstName | varchar(20) | YES | | NULL | |
| lastName | varchar(20) | YES | | NULL | |
| createdAt | datetime | NO | | NULL | |
| updatedAt | datetime | NO | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
友谊:
+-----------+-------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------------------------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| status | enum('PENDING','ACCEPTED','DENIED') | NO | | NULL | |
| createdAt | datetime | NO | | NULL | |
| updatedAt | datetime | NO | | NULL | |
| user_1 | int | YES | MUL | NULL | |
| user_2 | int | YES | MUL | NULL | |
+-----------+-------------------------------------+------+-----+---------+----------------+
邮政:
+-----------+--------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| content | varchar(1000) | NO | | NULL | |
| status | enum('ACTIVE','DELETED') | NO | | NULL | |
| createdAt | datetime | NO | | NULL | |
| updatedAt | datetime | NO | | NULL | |
| UserId | int | YES | MUL | NULL | |
+-----------+--------------------------+------+-----+---------+----------------+
在 sequelize 中可以通过以下方式完成:
const User = sequelize.define('User',{
firstName: {
type: DataTypes.STRING(20),
allowNull: true,
},
lastName: {
type: DataTypes.STRING(20),
allowNull: true,
}
})
User.associate = models => {
User.hasMany(models.Friendship, { foreignKey: "user_1" });
User.hasMany(models.Friendship, { foreignKey: "user_2" });
};
const Post = sequelize.define('Post',{
content: {
type: DataTypes.STRING(1000),
allowNull: false,
},
status: {
type: DataTypes.ENUM("ACTIVE", "DELETED"),
allowNull: false,
default: "ACTIVE"
}
}
);
Post.associate = models => {
Post.belongsTo(models.User);
};
const Friendship = sequelize.define('Friendship', {
status: {
type: DataTypes.ENUM("PENDING", "ACCEPTED", "DENIED"),
allowNull: false,
default: "PENDING"
}
});
用法:
const models = require("./models")
const { Op } = require("sequelize");
const { User, Friendship, Post } = models;
const requestPost = async (user_id,post_id) => {
let user = await User.findOne({ where: { id: user_id } })
let post = await Post.findOne({ where: { id: post_id }, include: [User] })
let isFriend = await Friendship.findOne({
where: {
[Op.or]: [
{
user_1: user.id,
user_2: post.User.id,
status: "ACCEPTED"
},
{
user_1: post.User.id,
user_2: user.id,
status: "ACCEPTED"
}
]
}
})
if (isFriend) return post;
}
let run = async () => {
await models.sequelize.sync({ force: true });
let user1 = await User.create({
firstName: "dummy1",
lastName: "dummy1"
})
let user2 = await User.create({
firstName: "dummy2",
lastName: "dummy2"
})
let user3 = await User.create({
firstName: "dummy3",
lastName: "dummy3"
})
let user1_user2_friendship_accepted = await Friendship.create({
user_1: user1.id,
user_2: user2.id,
status: "ACCEPTED"
})
let user1_user3_friendship_pending = await Friendship.create({
user_1: user1.id,
user_2: user3.id,
})
let user1_post = await Post.create({
UserId: user1.id,
content: "Dummy-content"
})
// Example 1:
// user2 wants to access user1_post:
let getPost1 = await requestPost(user2.id, user1_post.id) // returns post
// Example 2:
// user3 wants to access user1_post:
let getPost2 = await requestPost(user3.id, user1_post.id) // returns undefined
console.log("\n\n\n\n")
if (getPost1) console.log("Returned getPost1")
if (getPost2) console.log("Returned getPost2")
}
run()
关于javascript - 如何在express中使用sequelize检索用户帖子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61957086/