我的user_contracts
表格有contract_type
和contract_id
,并使用STI
:
class UserContract < ActiveRecord::Base
belongs_to :user
belongs_to :contract, polymorphic: true
end
UserContract
中的属性如下所示:
["id", "user_id", "quantity", "contract_id", "contract_type", "created_at", "updated_at"]
UserContract
属于三种类型的合同BondContract
,EquityContract
和DerivativeContract
,如下所示:
[193] pry(main)> EquityContract.attribute_names.inspect
=> "[\"id\", \"ticker\", \"name\", \"country\", \"currency\", \"instrument_type\", \"created_at\", \"updated_at\", \"industry_group\"]"
我正在创建一个看起来像这样的查询:
UserContract.
joins("INNER JOIN bond_contracts ON bond_contracts.id = user_contracts.contract_id").
joins("INNER JOIN equity_contracts ON equity_contracts.id = user_contracts.contract_id").
joins("INNER JOIN derivative_contracts ON derivative_contracts.id = user_contracts.contract_id").
where(user_id: user_ids)
如何根据相关表格(BondContract,EquityContract和DerivativeContract)选择记录,以及相关表格是否有currency == @currency unless @currency.nil?
?我想获得一个UserContracts列表,其中相关的表货币字段等于某些标准。
答案 0 :(得分:1)
使用类似:
query = UserContract.joins... # as above
query = query.where(bond_contracts: {currency: @currency}) if @currency.present?
答案 1 :(得分:1)
如果预期用途不是玩具,在大多数情况下都不会出现多态关联。它不会扩展(额外的db命中和令人讨厌的查询),它会否定索引(冒多个完整的表格风险)基于这些长查询)并且无法在dbms中强制执行引用完整性。
相反:为每种合约类型使用HMT和联接表。要获取每个用户的所有类型的合同,在每个合同类型中使用参数化范围...它将避免很多SQL渣滓(可能需要一些,但首先尝试以标准方式进行)。要获取某个用户的所有合同,只需合并所有合同类型。
scope :by_user, ->(user) { where(user: user) }
scope :by_industry_group, ->(industry_group) { where(industry_group: industry_group) }
...
# Then
SomeContract.by_user(john).by_industry_group(airlines)
```
另一个想法是使用伪模型presenter Contract
类,它聚合来自多个底层模型的所有合同以在表单上显示......它不会有完整的AR支持,但它可以在更加规范化的数据库体系结构中,可以更轻松地处理多种Contract类型。
另请参阅Rails Guides