如何查询相关联接表中的字段?

时间:2016-03-10 09:44:37

标签: ruby-on-rails activerecord

我的user_contracts表格有contract_typecontract_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属于三种类型的合同BondContractEquityContractDerivativeContract,如下所示:

[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列表,其中相关的表货币字段等于某些标准。

2 个答案:

答案 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