识别没有与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。