识别没有与SQL查询的支付关联的资源

我有一个索引页面,我想要显示特色和标准板。 特色板有一个付款,标准板没有。

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) 

但这两者都返回了特色和标准板。

我正在寻找一种方法来获得标准列表(没有付款的电路板),我只是无法弄清楚如何做到这一点。

 Board .joins("LEFT JOIN payments ON boards.id = payments.board_id") .where(payments: {id: nil}) 

我强烈建议你阅读这篇伟大的博客文章,想象所有不同的联接 。 它还解释了您的使用案例:您首先离开加入董事会的付款,然后筛选出所有付款的董事会。

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

 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; 

在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。