[英]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.