Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 选择集合的补码_Ruby On Rails_Ruby On Rails 3_Activerecord - Fatal编程技术网

Ruby on rails 选择集合的补码

Ruby on rails 选择集合的补码,ruby-on-rails,ruby-on-rails-3,activerecord,Ruby On Rails,Ruby On Rails 3,Activerecord,我使用的是Rails 3.0。我有两张桌子:挂牌和优惠。一个清单有许多优惠。报价可以是接受为真或假 我想选择每个没有accepted为true的报价的列表。我试过了 Listing.joins(:offers).where('offers.accepted' => false) 但是,由于一个清单可以有许多报价,因此这会选择每个有未接受报价的清单,即使该清单有接受的报价 如果不清楚,我想要的是集合的补码: Listing.joins(:offers).where('offers.acce

我使用的是Rails 3.0。我有两张桌子:挂牌和优惠。一个清单
有许多
优惠。报价可以是
接受

我想选择每个没有
accepted
为true的报价的列表。我试过了

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
类列表true)
结束
结束

我更希望该解决方案在数据库端运行过滤。

首先想到的是在数据库中执行与现在基本相同的操作

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))
}

我相信使用外部连接和分组可以更干净地完成这项工作,但我不会马上想到:-)

谢谢!这比我以前做的要快得多。最让我感到惊讶的是,我在互联网上没有找到解决这个问题的方法——这似乎是一个比较常见的问题。警告——如果没有公认的答案,那么
ids
是空的。这将使中的
not_失败,并且将不选择任何内容!我在
ids
声明的正下方添加了
ids |=[0]
,效果非常好。