Reputation: 26048
I want to define 2 methods in Mongoid: expensive? and the scope for it. Here is what I'm doing:
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
So I want to able to find items the following ways:
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
They don't work. For instance, MyItem.where(:expensive?)
says undefined method each_pair for :expensive?:Symbol
Especially I want to figure out how to do the method or scope which will work as an instance method (not a class method) - items.expensive
Upvotes: 0
Views: 85
Reputation: 34328
I don't have experience with Mongoid, so the answer might not be fully correct, but to me it seems you are mixing two things: database querying, and calling methods on an instance.
They are two separate things and can not be intermixed. For example:
def expensive?
price >= 10
end
...is not a database query method. You're simply looking at an instance variable and checking if it's >= 10. Therefore you can't use this method in database queries since it's not a query construct.
But to make it work should not be too hard. All you need to change is this:
scope :expensive ... do
is_expensive ? where(:price.gte => 10) : where(:price.lt => 10)
end
The argument to where
must always be a Mongoid query expression. It cannot be something else.
Now your setup should work. You can ask everything you need:
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
However this is will not work:
MyItem.where(:expensive?)
Because :expensive?
is not a valid query expression, which is what is always needed as an argument to where
.
Upvotes: 3