如何使用轨道和 mongoid 通过关联"count"查找记录?



使用这些模型:

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.

最新更新