范围和方法做同样的事情

时间:2022-10-30 07:31:40

I want to define 2 methods in Mongoid: expensive? and the scope for it. Here is what I'm doing:

我想在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

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

它们不起作用。例如,MyItem.where(:昂贵的?)表示未定义的方法each_pair:昂贵?:符号

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

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

1 个解决方案

#1


3  

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.

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

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.

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

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.

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

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.

因为:贵吗?不是一个有效的查询表达式,它始终需要作为where的参数。

#1


3  

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.

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

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.

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

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.

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

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.

因为:贵吗?不是一个有效的查询表达式,它始终需要作为where的参数。