我创建了一个应用程序,它根据传递给它的多个服务查找服务提供者。这是通过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的服务提供商”。
是否可以在单个查询中执行此类过滤,或者我是否需要执行复合查询,或者只是循环查看结果并将其从列表中删除,如果它们不支持所有必需的服务?
答案 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”的块。