如何在Rails中使用命名作用域进行独占而非包容性查询?

时间:2010-01-25 05:22:37

标签: sql ruby-on-rails has-many-through

我创建了一个应用程序,它根据传递给它的多个服务查找服务提供者。这是通过many_through完成的,因此有一个连接对象。基本上,如果用户要求服务提供商提供服务A和服务B,我的范围将返回提供服务A和服务B的服务提供商或提供服务A或服务B的其他服务提供商。而不是我们想要将其限制为仅提供BOTH服务的提供商。

我的范围如下:

  named_scope :with_services, lambda { |services| {
      :conditions => ["services.id IN (#{services.map{|s| s.id}.join(', ')}) 
                        AND service_options.service_owner_type='ServiceProvider' 
                        AND service_options.service_owner_id = service_providers.id"],
      :include => [:services, :service_options]
    }
  }

正如您所看到的,我正在使用IN运算符来执行此操作。但IN就像是说“给我任何有服务A或服务B的提供者”,当我真正想要的是“给我任何同时拥有服务A和服务B的服务提供商”。

是否可以在单个查询中执行此类过滤,或者我是否需要执行复合查询,或者只是循环查看结果并将其从列表中删除,如果它们不支持所有必需的服务?

1 个答案:

答案 0 :(得分:1)

我认为您可以通过为服务A和B中的每一个提供服务列表来实现。

因此要么修改范围要采取两个列表:

:conditions => ["services.id IN (service_a) AND services.id IN (service_b)"] 

您甚至可以实际调用范围两次

 Model.with_services(service_a).with_services(service_b)

此外,无需额外费用,您可以缩短数组操作以查找ID:

services.collect(&:id).join

&:id相当于使用“| o | o.id”的块。