Sql 范围与rails中的两个关联

Sql 范围与rails中的两个关联,sql,ruby-on-rails,scope,associations,rails-activerecord,Sql,Ruby On Rails,Scope,Associations,Rails Activerecord,我在Rails中有以下范围 scope :with_active_services, Contact.joins(:i_services, :c_services).merge(IService.enabled).merge(CService.enabled) 我试图实现的是选择一个启用I_服务或c_服务的联系人。联系人不必同时具有这两个属性 我遇到了一些我无法解决的问题 范围目前的方式意味着联系人需要同时返回已启用的i_服务和c_服务 当我使用生成的SQL并将和的WHERE条件更改为或时,我

我在Rails中有以下范围

scope :with_active_services, Contact.joins(:i_services, :c_services).merge(IService.enabled).merge(CService.enabled)
我试图实现的是选择一个启用I_服务或c_服务的联系人。联系人不必同时具有这两个属性

我遇到了一些我无法解决的问题

范围目前的方式意味着联系人需要同时返回已启用的i_服务和c_服务

当我使用生成的SQL并将和的WHERE条件更改为或时,我遇到了一个问题,即联系人仍然需要同时返回c_服务和I_服务

我如何修改它以满足我的要求


谢谢。

您可以使用一些别致的SQL来实现这一点。大概是这样的:

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")
}

这将排除任何未加入任何已启用服务的联系人。

不幸的是,Rails不支持任何查询方法的“或”谓词。不过,您可能可以使用ARel来实现这一点,例如checkout。但不确定是否可以使用现有作用域。