我有一个联接表lab_tests
,它存储了特定实验室对lab_id
和test_id
架构的测试列表。
我想获得一个实验室列表,其中包含所有传递给参数的测试。
我目前有以下范围 -
scope :test_filter, lambda {|test_id|
return nil if test_id.blank?
where(:test_id => test_id)
}
但这给了我一份至少有一次测试的实验室清单。如何获得包含给定参数中所有测试的实验室列表?
答案 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
进行分组,并仅返回组中与测试次数相同的记录。即它仅返回那些至少具有所有给定测试的实验室。