Rails多对多关联下通过中间模型获取指定状态Unit的关联实现
解决方案:通过复合外键关联实现查询
要在UnitTypeCompound中通过has_many关联直接获取对应活跃状态的Unit,关键是利用复合外键匹配Unit的unit_type_id和compound_id两个字段,同时附加状态筛选条件。
步骤1:定义正确的关联关系
在UnitTypeCompound模型中添加以下关联:
# app/models/unit_type_compound.rb has_many :active_units, -> { where(status: 'active') }, primary_key: [:unit_type_id, :compound_id], foreign_key: [:unit_type_id, :compound_id], class_name: 'Unit'
如果希望代码更语义化,可以先在Unit模型中定义活跃状态的 scope:
# app/models/unit.rb scope :active, -> { where(status: 'active') } # 然后在UnitTypeCompound中简化关联 has_many :active_units, -> { active }, primary_key: [:unit_type_id, :compound_id], foreign_key: [:unit_type_id, :compound_id], class_name: 'Unit'
为什么之前的尝试失败?
- 第一种方式
has_many :units, through: :unit_type仅通过unit_type_id关联Unit,完全忽略了UnitTypeCompound中的compound_id,所以无法筛选出同时属于对应小区和户型的单元。 - 带
source的关联配置错误是因为没有指定复合外键,导致Rails错误地将units.id与unit_type_compounds.compound_id关联,逻辑完全偏离需求。
使用示例
现在你可以直接通过UnitTypeCompound实例获取符合条件的活跃单元:
# 获取某条UnitTypeCompound对应的所有活跃Unit unit_type_compound = UnitTypeCompound.find(1) unit_type_compound.active_units
生成的SQL会自动包含正确的关联条件:
SELECT "units".* FROM "units" WHERE "units"."status" = 'active' AND "units"."unit_type_id" = $1 AND "units"."compound_id" = $2
内容的提问来源于stack exchange,提问作者KhogaEslam
相关产品推荐
相关产品推荐

