0

我想在 Mongoid 中定义 2 种方法:昂贵?及其适用范围。这是我正在做的事情:

class MyItem
  include Mongoid::Document
  include Mongoid::Timestamps

  # it could find expensive and cheap items depending of is_expensive parameter
  scope :expensive, ->(is_expensive = true) do
    if is_expensive
      where(:expensive?)
    else
      not_in(:expensive?)
    end
  end

  def expensive?
    price >= 10 # $10
  end
end

所以我希望能够通过以下方式找到项目:

  MyItem.expensive #find all expensive ones
  MyItem.where(:expensive?) #the same as above
  MyItem.first.expensive? #check if it's expensive
  items.expensive # items is the collection of MyItem

他们不工作。例如,MyItem.where(:expensive?)undefined method each_pair for :expensive?:Symbol

特别是我想弄清楚如何做将作为实例方法(不是类方法)工作的方法或范围 -items.expensive

4

1 回答 1

3

我没有使用 Mongoid 的经验,所以答案可能并不完全正确,但对我来说,您似乎混合了两件事:数据库查询和在实例上调用方法。

它们是两个独立的东西,不能混为一谈。例如:

def expensive? 
  price >= 10
end

...不是数据库查询方法。您只是查看一个实例变量并检查它是否 >= 10。因此,您不能在数据库查询中使用此方法,因为它不是查询构造。

但要让它工作不应该太难。所有你需要改变的是:

scope :expensive ... do
  is_expensive ? where(:price.gte => 10) : where(:price.lt => 10)
end

to 的参数where必须始终是Mongoid 查询表达式。它不可能是别的东西。

现在您的设置应该可以工作了。你可以问你需要的一切:

MyItem.expensive          # Returns a collection of expensive items
MyItem.first.expensive?   # Calls the instance method. Returns true or false
items.expensive           # Returns all expensive items in the collection

但是,这是行不通的:

MyItem.where(:expensive?)

因为:expensive?不是一个有效的查询表达式,它总是需要作为where.

于 2013-02-06T07:52:26.267 回答