Postgresql 续集如何构造应用程序的聊天部分?
我目前有一个应用程序,用户可以登录并发表文章。在每个帖子旁边,有一个按钮,如果按下,当前用户可以向创建帖子的用户发送消息 我有一个posts模型和一个用户模型。每个用户可以发布任意数量的帖子,但每个帖子只属于一个用户Postgresql 续集如何构造应用程序的聊天部分?,postgresql,sequelize.js,Postgresql,Sequelize.js,我目前有一个应用程序,用户可以登录并发表文章。在每个帖子旁边,有一个按钮,如果按下,当前用户可以向创建帖子的用户发送消息 我有一个posts模型和一个用户模型。每个用户可以发布任意数量的帖子,但每个帖子只属于一个用户 const User = db.define( "User", { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, }, name: { type: Se
const User = db.define(
"User",
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
},
email: {
type: Sequelize.STRING,
},
password: {
type: Sequelize.STRING,
},
},
);
const Post = db.define(
"Post",
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
title: {
type: Sequelize.STRING,
},
subTitle: {
type: Sequelize.STRING,
},
userId: {
type: Sequelize.INTEGER,
},
},
);
User.hasMany(Post,
{ foreignKey: "userId" }
);
Post.belongsTo(User,
{ foreignKey: "userId" }
);
我现在尝试实现的是消息传递功能
以下是迄今为止我的消息模型:
const Messages = db.define("Messages", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
senderId: {
type: Sequelize.STRING,
},
receiverId: {
type: Sequelize.STRING,
},
message: {
type: Sequelize.STRING,
},
});
User.hasMany(Messages, {
foreignKey: 'senderId'
});
User.hasMany(Messages, {
foreignKey: 'receiverId'
});
Messages.associate = (models) => {
Messages.belongsTo(models.Post, {
foreignKey: "PostId",
});
Messages.belongsTo(models.User, {
foreignKey: "senderId",
});
Messages.belongsTo(models.User, {
foreignKey: "receiverId",
});
};
User.hasMany(Conversations, {
foreignKey: 'conversationId'
});
const Conversations = db.define("Conversations", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
}
});
module.exports = Conversations;
Conversations.associate = (models) => {
Conversations.hasMany(models.Message);
models.Message.belongsTo(Conversations);
};
这是我迄今为止的对话模式:
const Messages = db.define("Messages", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
senderId: {
type: Sequelize.STRING,
},
receiverId: {
type: Sequelize.STRING,
},
message: {
type: Sequelize.STRING,
},
});
User.hasMany(Messages, {
foreignKey: 'senderId'
});
User.hasMany(Messages, {
foreignKey: 'receiverId'
});
Messages.associate = (models) => {
Messages.belongsTo(models.Post, {
foreignKey: "PostId",
});
Messages.belongsTo(models.User, {
foreignKey: "senderId",
});
Messages.belongsTo(models.User, {
foreignKey: "receiverId",
});
};
User.hasMany(Conversations, {
foreignKey: 'conversationId'
});
const Conversations = db.define("Conversations", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
}
});
module.exports = Conversations;
Conversations.associate = (models) => {
Conversations.hasMany(models.Message);
models.Message.belongsTo(Conversations);
};
此外,消息可以从一个用户发送到另一个用户,而不是发送到一组用户
我的关联和表结构正确吗
更新
在尝试发送消息时使用此实现,messages表中的conversationId为null
以下是我的发帖请求:
router.post("/",
auth,
async (req, res) => {
const post = await Post.findOne({where:{id:req.body.postId}})
if (!post) return res.status(400).send({ error: "Invalid postId." });
const targetUser = await User.findOne({where:{post.userId}})
if (!targetUser) return res.status(400).send({ error: "Invalid
userId." });
await Conversations.findOne({
where:{
user1:{[Op.or]:[req.user.id,post.userId]},
user2:{[Op.or]:[req.user.id,post.userId]},
PostId:req.body.postId,
}
}).then(conversation=>{
if(conversation){
return conversation
}else{
return Conversations.create({
user1: req.user.id,
user2: post.userId,
PostId:req.body.postId,
})
}
}
)
Messages.create({
senderId: req.user.id,
receiverId: post.userId,
message: req.body.message,
conversationId:conversation.id //MY PROBLEM IS HERE
})
.then(
res.status(201).send({
msg: "upload successful",
}));
const { expoPushToken } = targetUser;
if (Expo.isExpoPushToken(expoPushToken))
await sendPushNotification(expoPushToken, message);
});
所有型号看起来都不错。这些问题与协会有关 如果在相同的两个模型之间定义了多个关联,则应指示不同的别名,以便在查询中相互区分
User.hasMany(Messages, {
foreignKey: 'senderId',
as: 'OutgoingMessages'
});
User.hasMany(Messages, {
foreignKey: 'receiverId',
as: 'IncomingMessages'
});
另外,最好在模型定义之后直接以相同的方式定义关联,或者使用静态方法,如associate
。后一种方法更可取,因为它允许使用associate
方法中的models
参数在自己的模块中定义每个模型,而无需任何交叉引用,以访问应与给定模型关联的其他模型
最后一点注意:尝试定义关联,其中关联定义左侧的模型在其自己的associate
方法中。
意思是
models.Message.belongsTo(Conversations);
应在消息
模型关联方法中:
Message.belongsTo(models.Conversations);
这样,您总是知道在哪里可以找到定义从某个模型到其他模型的链接的所有关联
更新
您应该将找到的或创建的对话存储到变量中,以便在创建消息时使用它:
let conversation=wait Conversations.findOne({
其中:{
user1:{[Op.or]:[req.user.id,post.userId]},
user2:{[Op.or]:[req.user.id,post.userId]},
PostId:req.body.PostId,
}
})
如果(!对话){
对话=等待对话。创建({
user1:req.user.id,
user2:post.userId,
PostId:req.body.PostId,
})
}
const newMessage=等待消息。创建({
senderId:req.user.id,
receiverId:post.userId,
消息:req.body.message,
conversationId:conversation.id
})
资源状态(201)。发送({
msg:“上传成功”,
});
不要试图混淆
then/catch
和wait
。如果您使用wait
,您将已经有了一个结果或异常(您可以使用try/catch
)进行处理。所有型号看起来都不错。这些问题与协会有关
如果在相同的两个模型之间定义了多个关联,则应指示不同的别名,以便在查询中相互区分
User.hasMany(Messages, {
foreignKey: 'senderId',
as: 'OutgoingMessages'
});
User.hasMany(Messages, {
foreignKey: 'receiverId',
as: 'IncomingMessages'
});
另外,最好在模型定义之后直接以相同的方式定义关联,或者使用静态方法,如associate
。后一种方法更可取,因为它允许使用associate
方法中的models
参数在自己的模块中定义每个模型,而无需任何交叉引用,以访问应与给定模型关联的其他模型
最后一点注意:尝试定义关联,其中关联定义左侧的模型在其自己的associate
方法中。
意思是
models.Message.belongsTo(Conversations);
应在消息
模型关联方法中:
Message.belongsTo(models.Conversations);
这样,您总是知道在哪里可以找到定义从某个模型到其他模型的链接的所有关联
更新
您应该将找到的或创建的对话存储到变量中,以便在创建消息时使用它:
let conversation=wait Conversations.findOne({
其中:{
user1:{[Op.or]:[req.user.id,post.userId]},
user2:{[Op.or]:[req.user.id,post.userId]},
PostId:req.body.PostId,
}
})
如果(!对话){
对话=等待对话。创建({
user1:req.user.id,
user2:post.userId,
PostId:req.body.PostId,
})
}
const newMessage=等待消息。创建({
senderId:req.user.id,
receiverId:post.userId,
消息:req.body.message,
conversationId:conversation.id
})
资源状态(201)。发送({
msg:“上传成功”,
});
不要试图混淆
then/catch
和wait
。如果您使用wait
,您将已经有了一个结果或异常(您可以使用try/catch
)进行处理。对话是否可以与帖子完全无关?它们可以是任意两个用户之间的对话吗?实际上是的,对话将与一篇帖子相关(但相同的用户可以就不同的帖子进行不同的对话)。是的,一个对话仅在两个用户之间。对话是否可以与帖子完全无关?它们可以是任意两个用户之间的对话吗?实际上是的,对话将与一篇帖子相关(但相同的用户可以就不同的帖子进行不同的对话)。是的,一个对话只在两个用户之间。是的,如果一个对话总是链接到某个帖子,那么posted
应该在conversation
模型中,而不是在Message
模型中。是的,将conversationId
添加到Messages
是的,没错,类似这样的事情。但这对你来说是一大堆全新的问题和答案,所以)祝你好运!是的,有两条路线似乎是合乎逻辑的:1。创建对话(以及消息)2。在现有会话中创建消息是的,如果会话总是链接到某个帖子,那么postId
应该在conversation
模型中,而不是在message
model中是的,将conversationId
添加到Messages
是的,没错,是这样的。但这是一个全新的bu