【问题标题】:Rails 5 left_outer_join with specific saved ID具有特定保存 ID 的 Rails 5 left_outer_join
【发布时间】:2019-05-24 11:54:13
【问题描述】:

我的系统有以下型号

class Application < ApplicationRecord
  has_many :offers, dependent: :destroy
  belongs_to :accepted_offer, class_name: 'Offer', 
                              foreign_key: 'accepted_offer_id',
                              optional: true
class Offer < ApplicationRecord
  belongs_to :application

并且正在创建一个报告,收集accepted_offer_id 的所有报价,就像这样

Application.find_each do |app|
  offer = Offer.find(app.accepted_offer_id) if app.accepted_offer_id
  report.push(report_body(app, offer))
end

这变得太慢了,我想重写报告位,以便它利用左连接来与数据库的单查询建立连接。

我想让查询返回以accepted_offer_id 形式存储在应用程序表上的所有优惠。

Offer.left_outer_joins(:applications).where(id: { 'application.accetped_offer_id' })

我知道上面的内容是错误的,但我确定必须可以通过单个查询获取集合?

【问题讨论】:

  • 试试.where("application.accetped_offer_id IS NOT NULL")

标签: ruby-on-rails postgresql left-join


【解决方案1】:

这样的吗?

class Offer < ApplicationRecord
  belongs_to :application

  scope :accepted, -> { joins(:application).where('offers.id = applications.accepted_offer_id') } 
end

Offer.accepted

【讨论】:

  • 不确定这里的架构是什么,但这仅在 offers.application_id = application.idoffers.id = applications.accepted_offer_id 因为加入时才有效。如果这两个是单独的问题,则此查询将失败,例如如果一个 applications.accepted_offer_id 可以用于与不同应用程序关联的报价
  • 是的,我知道,但这应该适用于我想要的架构
【解决方案2】:

为了更好地重写第一个位:

Application.find_each do |app|
  report.push(report_body(app, app.accepted_offer)) if app.accepted_offer
end

继续重写 SQL,我很确定您需要做的是:

Offer.joins(:application).where('offers.id = applications.accepted_offer_id')

【讨论】:

    【解决方案3】:

    您也可以选择使用子查询。

    offer_ids = Application.select(:accepted_offer_id)
    offers = Offer.where(id: offer_ids)
    

    应该导致(MySQL):

    SELECT `offers`.*
    FROM `offers`
    WHERE `offers`.`id` IN (
      SELECT `applications`.`accepted_offer_id`
      FROM `applications`
    )
    

    【讨论】:

    • 请记住,#inspect 方法已经触发了查询(限制为 11)。仅当您将其复制到 Rails 控制台时才会出现问题。为防止出现这种情况,请在后面加上 ;nil。这样,结果就不会返回到控制台,而控制台又会调用#inspect 方法。或者,您可以将其包装到 begin/end 块中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多