ActiveRecord:如何做一个' OR'合并?

时间:2014-05-08 02:30:52

标签: ruby-on-rails ruby activerecord

我试图在模型中解耦ActiveRecord查询,以便它们可以在不同情况下重复使用。为了简单起见,我说有一个名为Product的模型:

class Product < ActiveRecord::Base
  def self.over_stocked
    where('stock_count >= ?', 20)
  end

  def self.expensive
    where('price >= ?', 100.0)
  end
end

如果我想创建一种新方法来查找库存过多且价格昂贵的产品,我可以合并这两个查询:

...
def self.costly_stock
  # SQL => '... WHERE stock_count >= 20 AND price >= 100.0'
  over_stocked.merge(expensive)
end

但是,如何使用这两种方法为昂贵或库存过多的产品创建新查询? E.g:

...
def expensive_or_over_stocked
  # SQL => '... WHERE stock_count >= 20 OR price >= 100.0'
  ...
end

基本上我正在寻找使用OR而不是AND的merge之类的东西。理想情况下,解决方案将返回ActiveRecord Relation而不是Array。显然我可以用where('stock_count >= ? OR price >= ?', 20, 100.0)重写查询,但这不会很干

1 个答案:

答案 0 :(得分:0)

我提出了以下解决方案。人们可以争论它是如何干的。

class Product < ActiveRecord::Base
  scope :over_stocked, -> { where.not(stock_count: [0..19]) }
  scope :expensive, -> { where.not(price: [0..99]) }
  scope :costly_stock, -> { expensive.over_stocked }
  scope :neither_expensive_nor_over_stocked, -> { where(stock_count: [0..19]).where(price: [0..99]) }

  def self.expensive_or_over_stocked
    Product.where.not(id: Product.neither_expensive_nor_over_stocked.pluck(:id))
  end
end