簡體   English   中英

如何根據Mongoid中的關系設置可鏈接范圍

[英]How do you set up chainable scopes based on relations in Mongoid

問題已解決......原來有一個活動的記錄方法已經過了寫,現在一切都按預期工作了

我正在嘗試設置范圍,以便我可以撥打電話

Competitor.of_type(type).at_event(event)

這將返回參加活動的所有類型的競爭對手My Models看起來像

class Competitor < Competitor
  belongs_to :type
  has_and_belongs_to_many :events
  scope :at_event, ->(event) {where(:event_ids.in => event.competitor_ids)}
  scope :of_type, ->(type) where(:type_id => type.id)                
end

以下作品(返回mongoid標准)

Competitor.of_type(type)
Competitor.at_event(event)

但當我鏈接它們時,它會打印出如下所示的內容:

#<Competitor:0x00000109e2b210>
#<Competitor:0x00000109e2ab08>
-------=-=------------------------------------
=> #<Mongoid::Criteria
selector: {},
options:  {},
class:    Competitor,
embedded: false>

每個Competitor.of_type(類型)都有一個競爭者條目(第一個鏈接標准),如果我在查詢上運行.count,我會得到數據庫中競爭者的總數。

在范圍的mongoid文檔的頂部,它表示所有范圍都是可鏈接的,並且也可以應用於關聯,后面將在關系部分中討論。 不幸的是我沒有看到關系子部分,我不能在主關系部分找到對范圍的單一引用。

我能夠得到以下內容以返回我想要的結果:

where(:id.in => event.competitor_ids).where(:type_id => type.id)

但如果查詢的任何部分被拆分為單獨的方法或范圍,它將失敗並提供我上面顯示的結果。

領域

與Active Record類似,Mongoid允許您在模型上定義范圍,以方便過濾結果集。 范圍是在類級別定義的,可以使用范圍宏,也可以通過定義返回條件對象的類方法來定義。 所有范圍都是可鏈接的,也可以應用於關聯,后者將在關系部分進行討論。

命名范圍是使用范圍宏在類級別定義的,並且可以鏈接以在不錯的DSL中創建結果集。

class Person
  include Mongoid::Document
  field :occupation, type: String
  field :age, type: Integer

  scope :rock_n_rolla, where(occupation: "Rockstar")
  scope :washed_up, where(:age.gt => 30)
  scope :over, ->(limit) { where(:age.gt => limit) }
end

# Find all the rockstars.
Person.rock_n_rolla

# Find all rockstars that should probably quit.
Person.washed_up.rock_n_rolla

# Find a criteria with Keith Richards in it.
Person.rock_n_rolla.over(60)

請注意,定義是在類加載時評估的。 要在運行時進行評估,您需要確保使用proc或lambda進行定義。 在以下示例中,第一個日期設置為類加載的日期,其中第二個范圍設置調用范圍時的日期。

scope :current, where(:start_date.lte => Date.today)
scope :current, -> { where(:start_date.lte => Date.today) }

類方法

對於那些喜歡Data Mapper樣式語法的人來說,返回條件的類方法也可以被視為可鏈接的范圍。

class Person
  include Mongoid::Document
  field :occupation, type: String
  field :age, type: Integer

  class << self

    def rock_n_rolla
      where(occupation: "Rockstar")
    end

    def washed_up
      where(:age.gt => 30)
    end

    def over(limit)
      where(:age.gt => limit)
    end
  end
end

# Find all the rockstars.
Person.rock_n_rolla

# Find all rockstars that should probably quit.
Person.washed_up.rock_n_rolla

# Find a criteria with Keith Richards in it.
Person.rock_n_rolla.over(60)

返回條件的命名范圍和類方法可以鏈接在一起 - 這是Mongoid強大的標准API的美妙之處。

class Person
  include Mongoid::Document
  field :occupation, type: String
  field :age, type: Integer

  scope :washed_up, where(:age.gt => 30)
  scope :over, ->(limit) { where(:age.gt => limit) }

  def self.rock_n_rolla
    where(occupation: "Rockstar")
  end
end

# Same queries apply here as well.
Person.rock_n_rolla
Person.washed_up.rock_n_rolla
Person.rock_n_rolla.over(60)

盡管@ MZaragoza的答案已經完成,但似乎不再允許這種語法:

scope :rock_n_rolla, where(occupation: "Rockstar")

改為使用過程:

summary:
  Scopes in Mongoid must be procs that wrap criteria objects.
resolution:
  Change the scope to be a proc wrapped critera.

 Example:
   class Band
     include Mongoid::Document
     scope :inactive, ->{ where(active: false) }
   end

Mongoid v 7.0.3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM