2013-02-06 32 views
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

回答

3

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

他们是两个单独的东西,不能混合。例如:

def expensive? 
    price >= 10 
end 

...不是数据库查询方法。您只是查看实例变量并检查它是否大于等于10.因此,您不能在数据库查询中使用此方法,因为它不是查询结构。

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

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

where的参数必须始终为Mongoid query expression。它不能是别的。

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

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

相关问题