Rails where_exists结合双深度关联模型的计数属性
Rails where_exists combined with counting attributes of double-deep associated models
我有一个 Filter
对象,has_many RelevanceLabels
与之关联。 RelevanceLabel
属于 Article
.
我想做一个丑陋的查询:我想找到所有 Filters
至少有 10 RelevanceLabels
,其中每个 RelevanceLabel
的 Article
没有有一个 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.*) >= ?", ?)
.
我有一个 Filter
对象,has_many RelevanceLabels
与之关联。 RelevanceLabel
属于 Article
.
我想做一个丑陋的查询:我想找到所有 Filters
至少有 10 RelevanceLabels
,其中每个 RelevanceLabel
的 Article
没有有一个 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.*) >= ?", ?)
.