【问题标题】:Identify Resource that Does Not Have a Payment Association with SQL query识别与 SQL 查询没有支付关联的资源
【发布时间】:2017-02-25 11:36:50
【问题描述】:

我有一个索引页,我想在其中显示特色板和标准板。特色版块有 has_one 付款,标准版块没有。

class Payment < ApplicationRecord
  belongs_to :board
end

class Board < ApplicationRecord
  has_one :payment
end

所以我可以通过加入付款并因此删除标准板来识别特色板。

Board.joins(:payment).where(category: category, confirmed: true)

现在我想通过以下方式获得标准列表:

Board.where(category: category, confirmed: true)

但这都会返回特色板和标准板。

我正在寻找一种获得标准列表(没有付款的板)的方法,但我不知道如何做到这一点。

【问题讨论】:

  • 查看下面的编辑答案
  • 我觉得特意寻求我的帮助然后忽略我的回答是很不礼貌的......
  • @TheCha͢mp 你的回答让我朝着正确的方向前进

标签: ruby-on-rails join activerecord


【解决方案1】:
Board
  .joins("LEFT JOIN payments ON boards.id = payments.board_id")
  .where(payments: {id: nil})

我强烈建议您read this great blog post visualizing all different joins。它还解释了您的用例:您首先离开加入带有付款的董事会,然后过滤掉所有 确实有付款的董事会。

【讨论】:

  • 应该是joins("LEFT JOIN payments ON boards.id = payments.board_id")
【解决方案2】:

处理这个问题的更组合方式是:

Board.references(:payment).where.not(payment: { id: nil })

我们鼓励您使用作用域来发挥自己的优势。例如:

class Board
  scope :with_payments, -> { includes(:payment) }
  scope :featured, -> { with_payments.where.not(payment: { id: nil }) }
end

Board.featured # => SELECT * FROM boards JOIN payments ON payments.board_id = board.id AND payments.id IS NOT NULL;

【讨论】:

    【解决方案3】:

    在您的 Board 模型中创建一个新列。

    class AddPaymentToBoards < ActiveRecord::Migration
      def change
        add_column :boards, :payment, :boolean, default: false
      end
    end
    

    然后更改您的支付控制器的创建方法以包含来自 Board 模型的此方法。

    Board.rb
    
    def payment_made
      self.update_attribute(:payment, true)
    end 
    

    如果您发布用于创建付款的代码,我可以为您提供更多帮助,但这应该是微不足道的。

    然后就可以创建作用域了

    scope :payment_made, -> { where payment: true }
    

    然后,您将能够使用Board.payment_made 返回支付布尔属性为 true 的 Boards。

    【讨论】:

      猜你喜欢
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      相关资源
      最近更新 更多