选择一组的补码

时间:2011-08-20 14:24:51

标签: ruby-on-rails ruby-on-rails-3 activerecord

我正在使用Rails 3.0。我有两张桌子:房源和优惠。清单has-many优惠。优惠可以acceptedtruefalse

我想选择每个没有商品的商品,其中accepted为真。我试过了

Listing.joins(:offers).where('offers.accepted' => false)

但是,由于上市可以有许多要约,因此即使有该上市的已接受要约,也会选择具有未接受要约的每个上市。

如果不清楚,我想要的是该集的补充:

Listing.joins(:offers).where('offers.accepted' => true)

我目前的临时解决方案是抓住所有这些,然后对阵列进行过滤,如下所示:

class Listing < ActiveRecord::Base
...
    def self.open
        Listing.all.find_all {|l| l.open? }
    end

    def open?
        !offers.exists?(:accepted => true)
    end
end

如果解决方案在数据库端运行过滤,我更愿意。

1 个答案:

答案 0 :(得分:1)

我想到的第一件事就是做你现在正在做的事情,但在数据库中。

scope :accepted, lambda {
  joins(:offers).where('offers.accepted' => true)
} 

scope :open, lambda {
  # take your accepted scope, but just use it to get at the "accepted" ids
  relation = accepted.select("listings.id")

  # then use select values to get at those initial ids
  ids = connection.select_values(relation.to_sql)

  # exclude the "accepted" records, or return an unchanged scope if there are none
  ids.empty? ? scoped : where(arel_table[:id].not_in(ids))
}

我确信使用外部联接和分组可以更干净地完成,但它不会立即找到我: - )