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の経験がないので、答えは完全には正しくないかもしれませんが、データベースのクエリとインスタンスのメソッドの呼び出しという2つのことを組み合わせているようです。

それらは2つの別個のものであり、混合することはできません。例えば:

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 に答える