【问题标题】:ActiveRecord get all models with a specific set of related models (AND not OR)ActiveRecord 获取具有一组特定相关模型的所有模型(AND 不是 OR)
【发布时间】:2020-01-04 14:49:04
【问题描述】:

我有一个汽车数据库,这些汽车具有特定的功能(例如座椅加热、LED 灯、交流电……)。

模型是这样设置的:

class Car < ApplicationRecord
  has_many :car_key_features
  has_many :key_features, through: :car_key_features
end

class CarKeyFeature < ApplicationRecord
  belongs_to :car
  belongs_to :key_feature
end

class KeyFeature < ApplicationRecord
  has_many :car_key_features
  has_many :cars, through: :car_key_features
end

我现在想要获得所有具有特定功能的汽车。例如,我想获取所有具有标识符“座椅加热”和“led-lights”功能的汽车(但它也可能具有其他功能)。

我使用以下查询进行了尝试,但这为我提供了至少具有其中一项功能的所有汽车,而不是全部(因为它会导致 SQL“IN”查询):

scope :by_key_features, ->(identifiers) { joins(:key_features).where(key_features: { identifier: identifiers }).group('cars.id') }

对此的任何帮助将不胜感激!

【问题讨论】:

    标签: ruby-on-rails ruby activerecord ruby-on-rails-6


    【解决方案1】:

    您的查询将选择至少具有一项匹配功能的所有汽车。因此,您只需要选择与查询中所有特征数量相同的汽车。

    scope :by_key_features, ->(identifiers) {
      joins(:key_features)
        .where(key_features: { identifier: identifiers })
        .group('cars.id')
        .having('COUNT(key_features.id) >= ?', identifiers.size) 
    }
    

    【讨论】:

    • 谢谢,但我认为这并不完全符合我的要求。如果我查询“座椅加热”和“LED 灯”,这还将返回具有这些功能之一以及其他功能的汽车,例如“空调”。
    • 这不应该发生,因为此查询将首先仅过滤匹配的行(where 部分),对它们进行分组,然后仅返回结果集中行数至少与那里的条件(having 部分)。此查询将返回具有更多功能的汽车(&gt;= 部分),但不会返回功能较少的汽车。你真的测试那个行为还是你只是认为它可能有那个行为?
    • 非常抱歉,这确实是我想要的!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2019-07-27
    • 2018-05-31
    相关资源
    最近更新 更多