我有一个索引页面,我想要显示特色和标准板。特色董事会已经付款,标准董事会没有。
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)
但这两者都会返回特色和标准板。
我正在寻找获得标准列表的方法(没有付款的主板),我只是无法弄清楚如何做到这一点。
答案 0 :(得分: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。它还解释了您的使用案例:您首先离开加入董事会的付款,然后过滤掉所有确实付款的董事会。
答案 1 :(得分:0)
处理这个问题的更多组合方式是:
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;
答案 2 :(得分:-1)
在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的单位。