加入表活动记录查询

时间:2016-05-26 04:30:09

标签: sql ruby-on-rails activerecord jointable

我有一个联接表lab_tests,它存储了特定实验室对lab_idtest_id架构的测试列表。

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

我目前有以下范围 -

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

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

1 个答案:

答案 0 :(得分:1)

您可以使用GROUP BY和HAVING来使用该技巧。如果您过滤了所有需要test_id的关联表并按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)
}

注意:

  • 如果为空test_ids,则范围会返回none scope。这是一种更好的方法,然后返回nil,因为none是一个正常的可链接范围,可以像其他范围一样使用(链接nil会抛出异常)。
  • 您尚未指定示波器所在的位置,因此我认为实验室模型可能是一个好地方 - 这样,示波器会使用至少给定的测试返回实验室。
  • 范围加入关联表,仅过滤那些test_ids的记录。 test_ids应该是实验室中想要的一组测试ID。该条件将作为SQL的IN条件中的WHERE子句运行。
  • 然后它使用分组技巧 - 它按lab_id进行分组,并仅返回组中与测试次数相同的记录。即它仅返回那些至少具有所有给定测试的实验室。
相关问题