ActiveRecord:在没有一个孩子满足特定条件的地方找到父母

时间:2019-05-21 16:22:45

标签: ruby-on-rails activerecord

我正在尝试使用Active Record在没有一个孩子满足特定条件的地方找到父母。

在我的应用程序中,用户可以在商品上发布出价。通过status枚举将一个出价设置为中标者。 我正试图返回没有中标项目的列表。

以下是相关代码:

# item.rb
class Item < ApplicationRecord
  has_many :bids
  scope :without_winner, -> { joins(:bids).where.not(bids: { status: :won }) }
end


# bid.rb
class Bid < ApplicationRecord
  belongs_to :item
  enum status: { pending: 0, won: 1, lost: 2 }
end

我的问题是,当前的:without_winner范围会每次 都返回一个竞标失败的商品。例如,如果我们有两个项目,每个项目都有三个出价:

Item 1
  Bid 1 (won)
  Bid 2 (lost)
  Bid 3 (lost)

Item 2
  Bid 4 (pending)
  Bid 5 (pending)
  Bid 6 (pending)

我当前的:without_winner范围将返回两次项1,两次返回项2。我想要的输出将仅返回Item 2一次,而根本不返回Item 1。

如何纠正我的范围,以返回没有中标的唯一商品列表?

2 个答案:

答案 0 :(得分:0)

尽管这是一个了不起的语法糖,但我已经有一段时间没有使用它了。但是,如果您确实遇到问题,可以尝试下面的类方法。它看起来很丑陋,但好处是它仅触发一个查询并根据您的要求进行过滤。

class Item < ApplicationRecord
  has_many :bids

  def self.without_winner
    includes(:bids).joins(:bids).distinct.reject do |item|
      item.bids.pluck(:status).include? :won
    end
  end
end

答案 1 :(得分:0)

您可以将.distinct添加到您的范围中,以清除重复项:

scope :without_winner, -> { joins(:bids).where.not(bids: { status: :won }).distinct }