加入 Table 个活动记录查询

Join Table Active Record Query

我有一个连接 table lab_tests,它存储特定实验室具有 lab_idtest_id.[=15= 架构的测试列表]

我想获得一个实验室列表,其中包含所有传递到参数中的测试。

我目前有以下范围 -

scope :test_filter, lambda {|test_id|
    return nil if test_id.blank?
    where(:test_id => test_id)
}

但这给了我至少有一项测试的实验室列表。如何获得包含给定参数中所有测试的实验室列表?

您可以使用 GROUP BY 和 HAVING 的技巧。如果您为所有想要的 test_id 筛选关联 table 并将其按 lab_id 分组,那么如果分组记录的数量与测试数量相同,您可以确定实验室包括所有这些测试(它可能包括一些其他测试,但我想你不介意)。

所以,尝试这样的事情:

# Lab model:
scope :with_tests, -> (test_ids) {
  return Lab.none if test_ids.blank?

  joins(:lab_tests).
    where(lab_tests: { test_id: test_ids }).
    group(:lab_id).
    having("count(*) = ?", test_ids.count)
}

备注:

  • 作用域returns一个none scope如果为空test_ids。这是一个比返回 nil 更好的方法,因为 none 是一个普通的可链接作用域,可以像其他作用域一样使用(链接 nil 会抛出异常)。
  • 你没有指定你的范围所在的位置,所以我认为实验室模型可能是一个好地方 - 这样范围 returns 实验室 至少给定的 测试。
  • 范围加入关联 table 并仅过滤那些具有 test_ids 的记录。 test_ids 应该是实验室中需要的一组测试 ID。条件将是 运行 作为 SQL.
  • WHERE 条件中的 IN 子句
  • 然后它使用分组技巧 - 它仅按 lab_id 和 returns 对组中测试次数与输入测试次数相同的记录进行分组。 IE。它 returns 仅 至少具有所有给定测试的实验室。