1

I have the following scope in Rails.

scope :with_active_services, Contact.joins(:i_services, :c_services).merge(IService.enabled).merge(CService.enabled)

What I'm trying to achieve is selecting a contact which has either enabled i_services or c_services. Contacts don't necessary have both.

I've run into a few problems which I cannot get my head around.

The way the scope is at the moment will mean a contact will need to have both an enabled i_service and c_service to be returned.

When I take the SQL generated and change the AND in the WHERE condition to OR I run into the problem that a contact still needs to have both a c_service and i_service to be returned.

How can I modify this to meet my requirements?

Thanks.

tereško
  • 58,060
  • 25
  • 98
  • 150
Malc
  • 55
  • 1
  • 8
  • Unfortunately Rails doesn't support "OR" predicates with any of the query methods. You might be able to use ARel for this though, checkout [this answer](http://stackoverflow.com/questions/3684311/rails-how-to-chain-scope-queries-with-or-instead-of-and) for an example. Not sure if it's possible to use existing scopes though. – Peter Brown Feb 05 '13 at 01:09

1 Answers1

0

You can do this with a touch of fancy SQL. Something like this:

scope :with_active_services ->() {
  joins("LEFT JOIN i_services ON contact.id = i_services.contact_id AND i_services.enabled")
  .joins("LEFT JOIN c_services ON contact.id = c_services.contact_id AND c_services.enabled")
  .group(:id)
  .where("(count(i_services.id) + count(c_services.id)) > 0")
}

This will exclude any contact that didn't join to any enabled services.

Shane
  • 514
  • 3
  • 6