首页 > 解决方案 > 具有多个用户的 Rails 模型

问题描述

我有点卡在一个问题上,我正在尝试制作一个消息传递系统。目前我有一个“聊天”模型(具有属性“名称”、作者 ID 和接收者 ID)和一个“消息”模型(具有属性“用户 ID”和“聊天 ID”)。

这样做的原因是因为我在另一个堆栈溢出答案中看到了它,而我只希望聊天室中只有 2 个人,而不是更多。现在的问题是,因为只有一个接收者和一个作者,所以很难对消息进行插值,因为我不能写“@chat.receiver.id”,因为我不知道 current_user 是接收者还是聊天的作者.

我真正想要的只是两个人之间的聊天,只有两个人可以看到。没有“聊天”模型,只有消息模型更好吗?或者有没有办法为聊天设置一个属性,我可以在其中存储多个 user_id,查看谁在里面,谁不在(这会很棒,因为我可以与超过 2 人进行群聊”

非常感谢你的帮助!

标签: ruby-on-rails

解决方案


这听起来像一个数据库建模问题!:)

聊天模型听起来不错(代表一个车队或房间?)但我不会在这里存储参与者(可以说你可能有一个创建它的“所有者” - 我认为这将是你的作者?)

通常,您在 Chat 和 User 之间会有 has_and_belongs_to_many (habtm) 关系,但您想强制执行 2 个人的列表,因此您需要定义一个 habtm 加入模型,例如属于 Chat 和 User 的“参与”,并且验证不超过2 个参与者(也可以存储有关他们参与的任何其他元数据)。

然后消息将属于 Chat 和 User,您可以验证消息是由参与的用户之一创建的。

我认为这是您最适合未来的模型(因为您提到了以后向更多人开放它的可能性)。

下面是一些大纲代码,用于显示模型关系以及您如何验证...

class User
  has_many :chats
  has_many :participations
  has_many :messages
end

class Chat
  belongs_to :user # the author  
  has_many :participations
  has_many :messages
end

class Participation
  belongs_to :chat
  belongs_to :user

  validate :validate_participant_limit

  def participant_limit?
    participations.count < 2
  end

private 
  
  def validate_particpant_limit
    return unless :participant_limit?
    errors.add(:user_id, "Maximum participants reached") 
  end    
end

class Message
  belongs_to :chat
  belongs_to :user

  validate :validate_chat_participant

  def by_author?
    message.user == message.chat.user
  end

private

  def validate_chat_participant
    return unless chat.participations.map(&:user).include? user
    errors.add(:user_id, "User is not in this chat") 
  end    

end

推荐阅读