如何使用嵌套关联查询STI驱动的模型?

时间:2018-01-31 11:40:08

标签: sql ruby-on-rails activerecord

我的要求是根据模型的嵌套关联编写一个查询,以根据STI上的模型检索记录。

以下是我的建模结果:

class Loan < ApplicationRecord
  belongs_to :borrower
end

class BusinessLoan < Loan
  belongs_to :business, inverse_of: :business_loans
end

class HousingLoan < Loan
end

class Borrower < ApplicationRecord
  has_many :loans
  has_one :address, as: :addressable
end

class Business < ApplicationRecord
  has_many :business_loans, inverse_of: :business
  has_one :address, as: :addressable
end

class Address < ApplicationRecord
  # COLUMN city, :string
  belongs_to :addressable, polymorphic: true
end

我想写一下,检索其业务或借款人在特定城市的所有贷款清单。

这就是我现在所拥有的:

cities = ["New York", "Washington"]

query_string = [
                Loan.select(:id).joins(borrower: :address).where(city: cities).to_sql,
                BusinessLoan.select(:id).joins(business: :address).where(city: cities).to_sql
               ].join(" UNION ")
Loan.where(id: Loan.find_by_sql(query_string))

我要求结果作为ActiveRecord关系,因此最后一个查询

有没有更好的方法来编写此查询?

1 个答案:

答案 0 :(得分:0)

看起来没有办法直接实现这一点,而无需在相关模型中编写一些新的范围。 Rails不允许在范围被启动的模型上无法进行任何操作。

但是,您仍然可以按如下方式解决问题以产生单个查询:

  1. from_citiesBorrower中定义Business范围,如下所示:
  2. scope :from_cities, ->(cities) { joins(:address).where("addresses.city IN (?)", cities) }
    
    1. 在贷款中定义from_cities以使用这些新范围:
    2. scope :from_cities, ->(cities) do
        where(borrower_id: Borrower.from_cities(cities)).
          or(where(business_id: Business.from_cities(cities)))
      end