我是 Rails 的新手,有些东西我不完全理解。
我有以下4个模型
class Unit
belongs_to :compound
belongs_to :unit_type
end
class UnitType
has_many :units
has_many :unit_type_compounds
has_many :compounds, through: :unit_type_compounds
end
class Compound
has_many :units
has_many :unit_type_compounds
has_many :unit_types, through: :unit_type_compounds
end
class UnitTypeCompound
belongs_to :unit_type
belongs_to :compound
end
我想通过一个
units
获得所有
unit_type_compound
[with active status]
我尝试了以下方法,但是当我检查查询时,我发现它是错误的
第一:
class UnitTypeCompound
belongs_to :unit_type
belongs_to :compound
has_many :units, through: :unit_type
end
query [for a single item
UnitTypeCompound.all.first.units
] 是这样的:
SELECT `units`.*
FROM `units`
INNER JOIN `unit_types` ON `units`.`unit_type_id` = `unit_types`.`id`
WHERE `unit_types`.`id` = 31
/* loading for inspect */
LIMIT 11
第二个:
class UnitTypeCompound
belongs_to :unit_type
belongs_to :compound
has_many :units, through: :unit_type, source: :unit_type_compounds
has_many :active_units, ->{ where(status: :active) }, class_name: Unit.to_s,
through: :unit_type, source: :unit_type_compounds
end
query [for a single item
UnitTypeCompound.all.first.units
] 是这样的:
SELECT `units`.*
FROM `units`
/* Note: the following condition is units.id not compounds.id */
INNER JOIN `unit_type_compounds` ON `units`.`id` = `unit_type_compounds`.`compound_id`
INNER JOIN `unit_types` ON `unit_type_compounds`.`unit_type_id` = `unit_types`.`id`
WHERE `unit_types`.`id` = 31
/* loading for inspect */
LIMIT 11
和查询 [for a single item
UnitTypeCompound.all.first.active_units
] 是这样的:
SELECT `units`.*
FROM `units`
/* Note: the same condition */
INNER JOIN `unit_type_compounds` ON `units`.`id` = `unit_type_compounds`.`compound_id`
INNER JOIN `unit_types` ON `unit_type_compounds`.`unit_type_id` = `unit_types`.`id`
WHERE `unit_types`.`id` = 31
AND `units`.`status` = 0
/* loading for inspect */
LIMIT 11
第三:
使用方法有效
class UnitTypeCompound
belongs_to :unit_type
belongs_to :compound
def vacant_units
Unit.where(status: :vacant)
.where(compound: compound)
.where(unit_type: unit_type)
end
end
但是,如果有办法通过
has_many
之类的,我会徘徊吗?
出于某些原因,您的场景不适合
has_many
。您处于 UnitTypeCompound
通过两个不同的关联有很多 units
的情况,并且您想要这两个关联的 units
的交集。
这不应该与
has_many
一起工作的第一个原因是,使用自然语言,您会期望如果 UnitTypeCompound
有很多单位,它将是这两个关联的联合,而不是交集。
第二个原因是
has_many
应该是可逆的。如果您调用unit.unit_type_compounds
,您会期望它是unit.unit_type.unit_type_compounds
,unit.compound.unit_type_compounds
,这两者的结合或它们的交集吗?
第三是您应该能够在关联上调用
collection<<
方法。如果你打电话给unit_type_compound.units << Unit.last
它应该通过UnitType
或Compound
创建那个关联吗?
你的场景有很多歧义,不能用简单的
has_many :units, through:
来表达,因此如果vacant_units
方法对你有用,我会坚持下去。