- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试使用 Node JS 和 Sequelize 创建一个聊天应用程序。现在我遇到了一个问题,即创建一个查询以查找具有我的 ID 和用户 ID 的对话(我正在尝试发短信的那个)。所以我想做的事情是发送一个帖子请求和我正在向其发送消息的用户的 id,然后我查看我的对话模型并检查该对话是否有我的 id 和用户的 id我发短信给。
我的模型通过多对多关系关联。所以主要目标是找到与 的对话。仅限 我的 ID 和我用 发短信的用户的 ID相同对话 ID。
这是我的模型:
用户
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
"User",
{
name: { type: DataTypes.STRING },
password: { type: DataTypes.STRING, allowNull: false },
username: { type: DataTypes.STRING, allowNull: false },
email: { type: DataTypes.STRING, allowNull: false },
},
{}
);
User.belongsToMany(models.Conversation, {
as: "conversations",
foreignKey: "user_id",
through: models.ConversationUsers,
});
User.hasMany(models.Message, {
as: "messages",
});
};
return User;
};
对话
module.exports = (sequelize, DataTypes) => {
const Conversation = sequelize.define(
"Conversation",
{
lastMessage: DataTypes.STRING,
recipients: DataTypes.ARRAY(DataTypes.INTEGER),
},
{
sequelize,
modelName: "Conversation",
}
);
Conversation.associate = (models) => {
Conversation.belongsToMany(models.User, {
as: "participants",
foreignKey: "conversation_id",
through: models.ConversationUsers,
});
Conversation.hasMany(models.Message, {
as: "messages",
});
};
return Conversation;
};
ConversationUsers 多对多通过模型
"use strict";
module.exports = (sequelize, DataTypes) => {
const ConversationUsers = sequelize.define(
"ConversationUsers",
{
user_id: DataTypes.INTEGER,
conversation_id: DataTypes.INTEGER,
},
{
sequelize,
modelName: "ConversationUsers",
}
);
return ConversationUsers;
};
信息
module.exports = (sequelize, DataTypes) => {
const Message = sequelize.define(
"Message",
{
conversationId: { type: DataTypes.INTEGER, allowNull: false },
sentTo: DataTypes.INTEGER,
sentFrom: DataTypes.INTEGER,
body: { type: DataTypes.STRING, allowNull: false },
},
{
sequelize,
modelName: "Message",
}
);
Message.associate = (models) => {
Message.belongsTo(models.User, {
as: "messageTo",
foreignKey: "sentTo",
});
Message.belongsTo(models.User, {
as: "messageFrom",
foreignKey: "sentFrom",
});
Message.belongsTo(models.Conversation, {
as: "messages",
});
};
return Message;
};
最佳答案
我认为您可以从模型中删除一些部分并对其进行一些修改。
消息不需要 sentTo
, 他们只需要一个 sentFrom
.您可以使用 ConversationUsers
表以了解收件人是谁。这也使您可以灵活地与超过 2 个成员进行对话,因为您当前的模型本质上强制消息只能发送给一个用户。
所以让我们先看看模型的变化
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
"User",
{
name: { type: DataTypes.STRING },
password: { type: DataTypes.STRING, allowNull: false },
username: { type: DataTypes.STRING, allowNull: false },
email: { type: DataTypes.STRING, allowNull: false },
},
{
// I think moving the associations to other files might make this more clear
}
);
};
return User;
};
module.exports = (sequelize, DataTypes) => {
const Conversation = sequelize.define(
"Conversation",
{
// perhaps something like a subject could go here e.g.
subject: DataTypes.STRING(500),
},
{
sequelize,
modelName: "Conversation",
}
);
Conversation.associate = (models) => {
Conversation.hasMany(models.Message, {
as: "ConversationMessages",
}); // adds ConversationId onto Message, gives us Conversation.getConversationMessages() etc
models.Message.belongsTo(Conversation); // create association both ways for convenience methods to find convo from a message
models.Message.hasOne(Conversation, {
as: 'LastMessage',
constraints: false,
allowNull:true,
defaultValue:null
}); // adds LastMessageId onto Conversation model (you'll have to write code to maintain this value, probably through an afterCreate hook on Message model)
};
return Conversation;
};
module.exports = (sequelize, DataTypes) => {
const Message = sequelize.define(
"Message",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true, // if you want to do the hook thing i talked about to set LastMessageId, you need to put this in
},
body: { type: DataTypes.STRING, allowNull: false },
},
{
sequelize,
modelName: "Message",
}
);
Message.associate = (models) => {
Message.belongsTo(models.User, {as: "sentFromUser"});
};
return Message;
};
// I'm going to rename your many-to-many table "ConversationMembers"
module.exports = (sequelize, DataTypes) => {
const ConversationMembers = sequelize.define(
"ConversationMembers",
{
// again, the associations will build these fields for you
},
{
sequelize,
modelName: "ConversationMembers",
}
);
models.Conversation.belongsToMany(models.User, {
through: "ConversationMember",
as: "Members",
}); // gives us Conversation.getMembers()
models.User.belongsToMany(models.Conversation, {
through: "ConversationMember",
as: "MemberConversations",
}); // gives us User.getMemberConversations()
ConversationMember.belongsTo(models.Message, { as: "LastReadMessage" }); // gives us the potential ability to track the last read message for each convo member as ConversationMember.LastReadMessageId, you'll need to set this value manually on read for each user if you care about having it
models.Conversation.hasMany(ConversationMember);
models.User.hasMany(ConversationMember);
return ConversationMember;
好的,现在回答您的问题,此时可能会变得更简单。如果您已经知道
ConversationId
,您需要做的就是检查发送消息的人是否是对话的成员。如果是,则在
Messages
中写入一行 table 。消息“发给”谁并不重要——你是在写给对话的成员,而不是给任何个人。
async function canMessageHelper({conversationId, userId }) {
const convo = await models.Conversation.findOne({
attributes: ["id"], // whatever attrs you need, probably not many if any
where: {
id: conversationId,
},
include: [{
model: models.ConversationMember,
attributes: ["ConversationId"], // whatever you need if anything
where: { // this where is critical, it creates an inner join so convo only returns if myUserId is a member of the Conversation
UserId: userId
}
}]
});
if (!convo) {
return false;
}
return convo;
}
async function sendMessage({conversationId, authorUserId, messageText}) {
const allowMessage = await canMessageHelper({conversationId, userId: authorUserId});
if (!allowMessage) {
return false;
}
await models.Message.create({sentFromUserId: authorUserId, body: messageText});
}
如果您想尝试此操作,请确保在同步之前从数据库中删除已使用这些名称创建的所有表。
关于node.js - Sequelize (PostgresQL) 多对多聊天实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64892798/
我想知道 gmail 聊天如何允许用户连接到 AIM,然后像登录到 AIM 一样聊天。 做起来容易吗?怎么做到的? 有人知道任何类似的开源工具吗? 谢谢! 最佳答案 如果你在谈论编程,这里是源代码示例
大家好,我正在尝试制作一个游戏,两个主持人联系起来,他们将“掷硬币”,并确定谁先出局。我决定从基本代码开始。但是我真的没有主意。 Thread server2 = new Thread(new Ser
我已经创建了一个只有 1 个房间的聊天室、私有(private)消息、审核以及一切,现在一切都很好!当我测试聊天时,我意识到在聊天中输入的所有消息都会被保存,如果有很多人使用聊天,它很快就会占用 Fi
当用户键入内容并出现软键盘时,我必须保持聊天回收器 View 的当前项目可见。目前,它覆盖了聊天,我需要回收器 View 项目与键盘一起显示。 我在 list 中尝试了这些: -android:win
我有一个服务器客户端应用程序集。 (家庭作业) 到目前为止,我已经弄清楚如何让多个客户端连接到服务器并让服务器聚合客户端发送的消息,以及如何让服务器将客户端的消息发送回客户端并将其显示在聊天 Pane
如何从我的应用程序发送/接收 Facebook 聊天消息?它是用 .Net、C# 编写的。 最佳答案 如果你可以使用 C,你就可以使用 libpurple (GPL) 和 pidgin-faceboo
我正在使用启用的 Ajax-Wcf 服务开发 Asp.Net 聊天。这是一个非常简单的聊天引擎,其中消息对话框意味着一对一(单个用户),但是我不知道如何管理(以最佳方式)通知新消息可用性。例如,假设有
我的任务是通过服务器构建一个客户端到客户端的聊天程序。客户端 A 将向服务器发送一条消息,然后服务器将消息转发给客户端 B,反之亦然。所有这一切都将同时发生,直到其中一个将其关闭。我有以下程序。 服务
我创建了一个聊天,用户可以在其中输入文本的输入字段。当他输入文本并按下发送(或输入)时,文本位于输入字段上方。像这样: 我想要的:我希望输入字段位于页面底部。我使用 position: absolut
出于个人兴趣,我尝试定义一个模拟 AI,它基于他学到的信息和互联网搜索,以便提供比系统知道的更多的细节。 我举了一个 child 的例子,当他出生时他需要学习一切,他听到了很多然后提出了一些答案。他的
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 3年前关闭。 Improve this qu
我已经开始聊天了,但我已经将用户的 ID 硬编码到 Chat.php 中。 当他们登录站点时,我的登录名将他们的电子邮件设置为 session ( $_SESSION['email']=$email;
当用户点击像 Start a viber chat with us 这样的链接时,我试图找到一种方法来开始 viber 聊天。但到目前为止我没有找到正确的URI来做到这一点。例如,我知道我可以使用 s
我是 Javascript(纯 javascript)新手,我正在尝试创建一个执行以下操作的聊天 Controller 应用程序。 用户输入内容。 有人对我的知识库进行了后调用。 服务器响应消息。 目
已关闭。这个问题是 not about programming or software development 。目前不接受答案。 这个问题似乎不是关于 a specific programming
如果用户在 x 秒/分钟内处于非事件状态,我想结束聊天,以便我们的代理不必等待聊天自行关闭。我还想在结束聊天之前将标签附加到聊天中,以便我可以看到这是由于不活动造成的。 最佳答案 此内容归功于 j
我正在此网站中构建新网站,客户需要 24/7 实时客户支持。我想在网站上集成 Skype 聊天 聊天界面应该在客户端的网站上。 最佳答案 您可以通过在网站上放置 Skype 按钮来使用它。 http:
事实上,我只是开始积极练习 swing,以便我的理论知识能派上用场:) 我已经为聊天 GUI 实现做了很多工作,但最终遇到了一些问题。所以我决定从头开始重新设计聊天 GUI,但我需要为其选择正确的组件
已关闭。这个问题是 not about programming or software development 。目前不接受答案。 这个问题似乎不是关于 a specific programming
我正在尝试进行简单的聊天,其中连接到服务器的用户发送消息,其他用户接收消息。 这是我的 html: function setupEventSource()
我是一名优秀的程序员,十分优秀!