簡體   English   中英

Rails中的復雜Postgres查詢

[英]Complex postgres query in rails

當前正在查詢具有參數premium_amount_lower_range, premium_amount_upper_range, application_date_lower_range, application_date_upper_range, insurance_type_id過濾器

@filtered_quotes = current_user.insurance_subscribers.includes(:insurance_types).includes(:insurance_subscribers_types, :insurance_subscribers_types_carriers).
                   premium_amount(params[:dashboard][:premium_amount_lower_range], params[:dashboard][:premium_amount_upper_range]).
                   duration(params[:dashboard][:application_date_lower_range], params[:dashboard][:application_date_upper_range]).
                   insurance_type(params[:dashboard][:insurance_type_id])

但是現在還需要根據其狀態進行過濾。 有問題。 我在insurance_subscribersinsurance_subscribers_types_carriers表中有“狀態”列,這兩個列都是枚舉。

我試圖添加where子句,例如

@filtered_quotes = current_user.insurance_subscribers.includes(:insurance_types).includes(:insurance_subscribers_types, :insurance_subscribers_types_carriers).
               where("insurance_subscribers_types_carriers.status = 1")
#              ...

這給了我錯誤PG::UndefinedTable: ERROR: missing FROM-clause entry for table "insurance_subscribers_types_carriers"

但是當我嘗試去喜歡

@filtered_quotes = current_user.insurance_subscribers.includes(:insurance_types).includes(:insurance_subscribers_types, :insurance_subscribers_types_carriers).
           where(status: 1)
#          .... 

這會將where子句放在insurance_subscribers上。

試圖在上述查詢中添加一個簡單的where子句WHERE insurance_subscribers_types_carriers.status = 1 ,但此查詢有很多麻煩。

協會

insurance_subscriber.rb

has_many :insurance_subscribers_types, dependent: :destroy
has_many :insurance_types, through: :insurance_subscribers_types
has_many :insurance_subscribers_types_carriers, through: :insurance_subscribers_types

insurance_types.rb

has_many :insurance_subscribers, through: :insurance_subscribers_types
has_many :insurance_subscribers_types
has_many :insurance_subscribers_types_carriers

insurance_subscriber_type.rb

belongs_to :insurance_subscriber
belongs_to :insurance_type
has_many :carriers, through: :insurance_subscribers_types_carriers
has_many :insurance_subscribers_types_carriers, dependent: :destroy

insurance_subscribers_types_carrier.rb

belongs_to :carrier
belongs_to :insurance_subscribers_type

如果要跨關聯模型添加queries ,則首先需要將它們加入。 由於您具有has_may :through關聯,因此可以按以下方式完成所需的操作:

InsuranceSubscriber.joins(insurance_subscriber_types: :insurance_subscribers_types_carriers)
.includes(:insurance_types, :insurance_subscribers_types, :insurance_subscribers_types_carriers)
.where("insurance_subscribers_types_carriers.status = ?", 1)

如您所見,即使您具有has_many :through ,也可以加入並引用您的關聯,如下所示joins(.joins(insurance_subscriber_types: :insurance_subscribers_types_carriers)

您將獲得sql的輸出,如下所示:

InsuranceSubscriber Load (3.3ms)  SELECT "insurance_subscribers".* FROM 
"insurance_subscribers" INNER JOIN "insurance_subscriber_types" ON 
"insurance_subscriber_types"."insurance_subscriber_id" = 
"insurance_subscribers"."id" INNER JOIN "insurance_subscribers_types_carriers" ON 
"insurance_subscribers_types_carriers"."insurance_subscriber_type_id" = 
"insurance_subscriber_types"."id" WHERE (insurance_subscribers_types_carriers.status = 1)

我使用模型結構復制並測試了您的問題,如下所示:

PS:我對您的型號名稱做了一些小的更改,因此請小心。 他們是如此簡化嘗試。

insurance_subscriber.rb

# == Schema Information
#
# Table name: insurance_subscribers
#
#  id         :integer          not null, primary key
#  name       :string
#  status     :integer          default("0")
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class InsuranceSubscriber < ActiveRecord::Base
  has_many :insurance_subscriber_types, dependent: :destroy
  has_many :insurance_types, through: :insurance_subscriber_types
  has_many :insurance_subscribers_types_carriers, through:     :insurance_subscriber_types

  enum status: {active: 0, passive: 1}
end

insurance_subscriber_types.rb

# == Schema Information
#
# Table name: insurance_subscriber_types
#
#  id                      :integer          not null, primary key
#  name                    :string
#  insurance_subscriber_id :integer
#  insurance_type_id       :integer
#  created_at              :datetime         not null
#  updated_at              :datetime         not null
#

class InsuranceSubscriberType < ActiveRecord::Base
  belongs_to :insurance_subscriber
  belongs_to :insurance_type

  has_many :insurance_subscribers_types_carriers, dependent: :destroy
  has_many :carriers, through: :insurance_subscribers_types_carriers
end

insurance_subscribers_types_carriers.rb

# == Schema Information
#
# Table name: insurance_subscribers_types_carriers
#
#  id                           :integer          not null, primary key
#  carrier_id                   :integer
#  insurance_subscriber_type_id :integer
#  status                       :integer          default("0")
#  created_at                   :datetime         not null
#  updated_at                   :datetime         not null
#

class InsuranceSubscribersTypesCarrier < ActiveRecord::Base
  belongs_to :carrier
  belongs_to :insurance_subscriber_type

  enum status: {active: 0, passive: 1}
end

insurance_types.rb

# == Schema Information
#
# Table name: insurance_types
#
#  id         :integer          not null, primary key
#  name       :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class InsuranceType < ActiveRecord::Base
  has_many :insurance_subscribers_types_carriers
  has_many :insurance_subscribers_types_carriers
  has_many :insurance_subscribers, through: :insurance_subscribers_types
end

如果要在查詢中使用包含的關聯(insurance_subscribers_types_carriers),則必須添加“引用”,否則insurance_subscribers_types_carriers將與主查詢分開加載:

InsuranceSubscriber.includes(:insurance_subscribers_types_carriers)
               .where("insurance_subscribers_types_carriers.status = ?", 1)
               .references(:insurance_subscribers_types_carriers)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM