我正在使用Rails 3.0。我有两张桌子:房源和优惠。清单has-many
优惠。优惠可以accepted
为true
或false
。
我想选择每个没有商品的商品,其中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
如果解决方案在数据库端运行过滤,我更愿意。
答案 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))
}
我确信使用外部联接和分组可以更干净地完成,但它不会立即找到我: - )