Как сделать эксклюзивный, а не инклюзивный запрос с именованными областями в Rails? - PullRequest
1 голос
/ 25 января 2010

Я создал приложение, которое находит поставщиков услуг на основе нескольких переданных ему услуг. Это делается с помощью many_through, поэтому есть объект соединения. По сути, если пользователь запрашивает поставщиков услуг с Услугами A и B, моя область возвращает поставщиков услуг, которые предлагают ОБА Услугу A и Услуги B, или других поставщиков услуг, которые предоставляют Услугу A или Услугу B. Вместо этого мы хотели бы ограничить его только теми поставщиками, которые предоставляют ОБА услуги.

Моя область видимости выглядит так:

  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 Ответ

1 голос
/ 25 января 2010

Я думаю, что вы, вероятно, можете сделать это, предоставив список услуг для каждой из услуг A и B.

Так что либо измените область видимости, чтобы взять два списка:

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

Возможно, вы даже сможете вызвать область дважды

 Model.with_services(service_a).with_services(service_b)

Также без каких-либо дополнительных затрат вы можете сократить ваши манипуляции с массивами, чтобы найти идентификаторы:

services.collect(&:id).join

&: id является эквивалентом блока, использующего «| o | o.id».

...