首页 > 解决方案 > 如何通过多个其他表检索关联记录?

问题描述

这是一个简单的设置,用户始终是患者,用户可能是也可能不是医生:

# user.rb
  has_one :physician
  has_one :patient
# physician.rb
  belongs_to :user
  validates_uniqueness_of :user_id
  has_many :appointments
  has_many :patients, :through => :appointments
# patient.rb
  belongs_to :user
  validates_uniqueness_of :user_id 
  has_many :appointments
  has_many :physicians, :through => :appointments

这一切都连接到约会,然后连接到对话,如下所示:

# appointment.rb
  belongs_to :physician
  belongs_to :patient
  has_one :conversation
  has_many :messages, through: :conversation
# conversation.rb
  belongs_to :appointment
  belongs_to :sender, foreign_key: :sender_id, class_name: "User"
  belongs_to :recipient, foreign_key: :recipient_id, class_name: "User"
  has_many :messages

有时我真的希望能够做到这一点:

current_user.conversations

但这不起作用,相反,我必须做这样的事情:

current_user.physician.appointment.includes(:conversation)
# somehow combine results with this
current_user.patient.appointment.includes(:conversation)

问题

我需要做什么(以及在哪里)才能打电话current_user.conversations,它会检索所有对话(即作为患者的对话作为医生的对话(注意用户可能是也可能不是医生)。

注意:如果我的建议不是好的做法,欢迎提出建议。

标签: ruby-on-railsactiverecordruby-on-rails-6rails-models

解决方案


根据您当前的设计,在User模型中,您可以简单地添加一个方法conversations

def conversations
  Conversation.where(sender: self).or(Conversation.where(recipient: self))
end

我不确定为什么对话会有一个sender,并且recipient作为用户,在对话中既可以是(消息的)发送者,也可以是(消息的)接收者。我会从表中删除sender_idand并仅匹配基于 的对话。recipient_idconversationsappointments

def conversations
  Conversation
   .joins(appointment: [:physician, :patient])
   .where('physicians.user_id = :user_id or patients.user_id = :user_id', user_id: id)
end

推荐阅读