使用这些模型:
class Week
has_many :proofs
end
class Proof
belongs_to :week
end
我想这样做:
Week.where(:proof.count.gt => 0)
只找到有多个证明的周。
有一个答案似乎可以解决这个问题:
rails作用域是否可以根据给定字段的关联类数量进行筛选
但是在这个例子中,Week中没有像proof_ids这样的属性,因为这些id是和证明一起存储的。这在以下示例中不起作用:
Week.where(:proof_ids.gt => 0)
这个查询是如何实现的?概念上很简单,但我不知道如何用mongo或monid做到这一点。
同样,我想按证明的数量排序,例如:
Week.desc(:proofs.size)
但这也行不通。
我确实意识到反缓存是我的两个特定问题的一个选项,但我也希望能够执行查询。
提前感谢您的帮助。
使用rails(不使用counter_cache),您可以这样做:
class Week < ActiveRecord::Base
has_many :proofs
def self.by_proofs_size
sort_by { |week| week.proofs.size }
end
def self.with_at_least_n_proofs(n = 1)
select { |week| week.proofs.size >= n }
end
end
尽管每个操作都会产生2个查询,但这还远远不够理想。
这对查询是重复的(每个操作=> 4个查询),范围(bug?):
scope :with_at_least_n_proofs, -> (n = 1) { select { |w| w.proofs.size >= n } }
scope :by_proofs_size, -> { sort_by { |w| w.proofs.size } }
理想的可能是使用counter_cache
scope :with_at_least_n_proofs, -> (n = 1) { where('proofs_count >= ?', n) }
scope :by_proofs_size, -> { order(proofs_count: :desc) }
我不知道这是否是最好的解决方案,因为它映射它通过一个数组,但这做的工作:(这里提到的其他解决方案给我的例外)
class Week < ActiveRecord::Base
scope :has_proofs, -> { any_in(:_id => includes(:proofs).select{ |w| w.proofs.size > 0 }.map{ |r| r.id }) }
end
对不起,如果我的方式-但你能使用一个简单的counter_cache在周表?然后你可以做week.proofs_count.