检查has_many关系中的所有记录是否与Rails SQL查询中的条件匹配

时间:2018-08-03 04:13:59

标签: sql ruby-on-rails

我正在尝试创建一个SQL查询,该查询基于has_many关系中记录的特定属性进行过滤。

我有一个具有has_many ivr_engagements的program.test,并且我想使用ivr_engagement.call_hook_number == 2查找没有ivr_engagements的测试。本质上,具有call_hook_number == 2的test.ivr_engagements的计数应该为零。

对象:

>> test.ivr_engagements
=> [#<IvrEngagement id: 281, user_id: 438431, testa_id: 508351, call_count: 1, call_hook_number: 1, qualified_response: true, ivr_application_id: 6741>, 
#<IvrEngagement id: 311, user_id: 438431, testa_id: 508351, call_count: 1, call_hook_number: 2, qualified_response: true, ivr_application_id: 6741>]

这些ivr_engagements中的一个具有2的call_hook_number。我想过滤掉所有具有与该条件匹配的ivr_engagement的测试。

该查询当前返回true(我希望它为false,因为有一条记录test.ivr_engagements的call_hook_number为2):

>> program.tests.find(:all, :include => [:ivr_engagements], :conditions => "ivr_engagements.call_hook_number != 2").include? test
=> true
>> 

我还尝试过:

>> program.tests.find(:all, :include => [:ivr_engagements], :conditions => "NOT EXISTS(SELECT 1 FROM ivr_engagements WHERE ivr_engagements.call_hook_number = 2)").include? test
=> false

我以为是可行的,但是当我删除问题ivr_engagement时,它应该返回true:

>> test.ivr_engagements
=> [#<IvrEngagement id: 281, user_id: 438431, testa_id: 508351, call_count: 1, call_hook_number: 1, qualified_response: true, ivr_application_id: 6741>, 
#<IvrEngagement id: 311, user_id: 438431, testa_id: 508351, call_count: 1, call_hook_number: 2, qualified_response: true, ivr_application_id: 6741>]
>> test.ivr_engagements.last.destroy
=> #<IvrEngagement id: 311, user_id: 438431, testa_id: 508351, call_count: 1, call_hook_number: 2, qualified_response: true, ivr_application_id: 6741>
>> program.reload.tests.find(:all, :include => [:ivr_engagements], :conditions => "NOT EXISTS(SELECT 1 FROM ivr_engagements WHERE ivr_engagements.call_hook_number = 2)").include? test
=> false

也尝试过:

>> program.tests.find(:all, :include => [:ivr_engagements], :conditions => "(SELECT count(*) FROM ivr_engagements WHERE ivr_engagements.call_hook_number = 2)=0")

但这也不起作用。

希望找到正确的查询。预先感谢!

2 个答案:

答案 0 :(得分:1)

在这种情况下,您可以使用Join,例如在您的示例中,您已经有该程序,那么我们可以使用它。

program.tests.joins(:ivr_engagements).where(:ivr_engagements => {call_hook_number: 2})

我们发现具有ivr_engagements且其call_hook_number值为2的测试。您也可以在同一查询中发送测试条件。

作为附带说明,如果以后有其他情况,则联接部分需要像单数或复数关系,但是第二个(在何处)需要复数,因为这是表的名称。 (在这种情况下是相同的,但是如果您要寻找一个属于,则很重要)

答案 1 :(得分:0)

获取程序的test_ids

test_ids = program.tests.pluck(:id)

现在根据您的情况获得IvrEngagement

IvrEngagement.where("testa_id IN (?) AND call_hook_number = ?", test_ids, 2)

或者,您也可以尝试:=>

Test.includes(:ivr_engagements).where("ivr_engagements.call_hook_number = ?", 2).distinct