ActiveRecord:如何使用AND语句查询多个关联?

时间:2015-06-30 03:08:53

标签: ruby-on-rails activerecord

所以我的产品具有多种功能,并且功能属于feature_key和feature_value。

以下是我正在运行的查询:

Product.family_features.joins(:feature_key, :feature_value)
       .where(feature_keys: { name: ["Color", "Size"] }, feature_values: { name: ["Red", "Large"] })
       .group_by(&:product_id)

注意.family_features是产品的范围,可获取与产品"家庭"相关的所有功能。 - 这是一组其他产品。

现在我只想要一种产品具有“#color;" color" => "红色"和"尺寸" => "大"

但我得到的功能有"颜色" => "红色"和其他尺寸,以及"尺寸" => "大"和其他颜色。

有没有办法将此查询约束为我需要的确切值组合?

关系看起来像这样:

Product has_many :features

Feature belongs_to :product, :feature_key, :feature_value

FeatureKey has_many :features, :products (through features)
FeatureValue has_many :features, :products (through features)

1 个答案:

答案 0 :(得分:0)

您应该可以使用arel。

执行此操作

fkt, fvt = FeatureKey.arel_table, FeatureValue.arel_table color_red = fkt[:name].eq('Color').and(fvt[:name].eq('Red')) size_large = fkt[:name].eq('Size').and(fvt[:name].eq('Large')) Feature.joins(:feature_key, :feature_value) .where(color_red.or(size_large)) .group(:product_id)

我没有测试过代码,但我认为它应该可行。 查看arel documentation了解详情。

请注意,我还将group_by更改为groupgroup_byEnumerable模块Ruby方法,而group是执行SQL GROUP BY的ActiveRecord关系方法,它应该比Ruby中的分组快得多。

编辑: 虽然您的评论说它有效但如果您需要所有具有size => largecolor => red组合的产品,我认为这不是您想要的。

您可以尝试这样的事情:

red_products = Product.joins(features: [:feature_key, :feature_value]).where({feature_keys: { name: 'color' }, feature_values: { name: 'red' }})
large_products = Product.joins(features: [:feature_key, :feature_value]).where({feature_keys: { name: 'size' }, feature_values: { name: 'large' }})
products = red_products & large_products

上述解决方案的问题是&是Ruby中的数组交集,因此它将进行两次数据库查询,并将结果与​​Ruby相交,这可能会成为大型数据集的问题。