如何正确配置Rails模型关联以实现预期内连接查询?
模型关联修正方案
问题分析
当前模型关联存在多处错误,导致生成的SQL出现重复关联patient_phases表的问题,核心问题点:
- Patient模型错误定义了
belongs_to :patient_phase,混淆了多对多关系逻辑 - PatientPhase模型中
belongs_to :patients使用复数违反Rails关联规则,且主键设置错误 - 关联定义中冗余的外键/主键指定,导致Rails无法正确推断关联链路
模型关联修正代码
1. RecruitmentPhase 模型
class RecruitmentPhase < ApplicationRecord belongs_to :cohort, optional: true belongs_to :parent, class_name: 'Cohort', required: false # 保留自定义主键关联,移除patients关联的冗余配置 has_many :patient_phases, dependent: :destroy, foreign_key: :phase_id, primary_key: :phase_id has_many :patients, through: :patient_phases end
2. PatientPhase 模型
class PatientPhase < ApplicationRecord # belongs_to 必须使用单数形式 belongs_to :patient, foreign_key: 'patient_id', primary_key: 'patient_id' # 明确与RecruitmentPhase的主键/外键映射 belongs_to :recruitment_phase, foreign_key: :phase_id, primary_key: :phase_id # 移除错误的单主键设置,连接表无需单独指定主键(如需复合主键可使用composite_primary_keys gem) end
3. Patient 模型
class Patient < ApplicationRecord has_many :patient_phases, foreign_key: 'patient_id', primary_key: 'patient_id' # 删除错误的belongs_to关联,多对多关系下一个患者可对应多个招募阶段 has_many :recruitment_phases, through: :patient_phases end
实现预期SQL的查询语句
从Patient模型出发构建查询,即可生成你需要的SQL结构:
Patient.joins(patient_phases: :recruitment_phase) .where(disease_code_id: 'KIN') .select('distinct patients.disease_code_id, recruitment_phases.phase_name, recruitment_phases.phase_id') .limit(11)
生成的SQL将与预期一致:
SELECT DISTINCT patients.disease_code_id, recruitment_phases.phase_name, recruitment_phases.phase_id FROM `patients` INNER JOIN `patient_phases` ON `patient_phases`.`patient_id` = `patients`.`patient_id` INNER JOIN `recruitment_phases` ON `recruitment_phases`.`phase_id` = `patient_phases`.`phase_id` WHERE `patients`.`disease_code_id` = 'KIN' LIMIT 11
内容的提问来源于stack exchange,提问作者raghu palakodety
相关产品推荐
相关产品推荐

