Rails where_exists结合双深度关联模型的计数属性

Rails where_exists combined with counting attributes of double-deep associated models

我有一个 Filter 对象,has_many RelevanceLabels 与之关联。 RelevanceLabel 属于 Article.

我想做一个丑陋的查询:我想找到所有 Filters 至少有 10 RelevanceLabels,其中每个 RelevanceLabelArticle 没有有一个 nil token_vector.

我目前正在使用 where_exists gem,这使得第一部分变得简单:

streams_with_labels = Filter.where_exists(:relevance_labels)

但后来我仍然在循环中诉诸丑陋:

    stream = Filter.find(filter_id)

    labels = stream.relevance_labels

    return if labels.length < 10

    labels_with_tokens = labels.reject { |label| label.article.token_vector.nil? }

    return if labels_with_tokens.length < 10

    ...

我确定有一些链接功能让我逃避了,但我什至不确定从哪里开始。

你可能想在这里做的只是围绕 filters.id 进行 GROUP 并添加一个 HAVING 子句来为每个组添加一个条件:

class Filter < ApplicationRecord
  has_many :relevance_labels 
  has_many :articles, through: :relevance_labels 

  def self.with_articles(n = 10)
    joins(:articles)
      .group(:id) # filters.id
      .where.not(articles: { token_vector: nil })
      .having(
        Article.arel_table[Arel.star].count.gte(n)
      )
  end
end

Article.arel_table[Arel.star].count.gte(n) 是一种更便携的写法 having("COUNT(articles.*) >= ?", ?).