否定ActiveRecord查询范围
我的模型范围略微复杂
class Contact { where(inactive: false) } scope :groups, -> { where(contact_type: 2308) } scope :group_search, -> (query) do active.groups.where("last_name LIKE '%' + ? + '%'", query) end end
出于测试目的,我想确保group_search
未返回的所有Contacts
都被排除在正确的原因之外。
但要获得该列表,我必须加载
Contact.all - Contact.group_search('query')
它运行两个查询,返回一个Array
而不是一个Relation
,并且比我想要的慢。
由于我正在测试group_search
范围,因此编写另一个负面范围会破坏这一点。 我宁愿做一些像:
Contact.merge.not(Contact.group_search('query'))
生成以下SQL查询:
SELECT * FROM contacts WHERE NOT (contact_type = 2308 AND inactive = 0 AND last_name LIKE '%' + ? + '%')
有没有办法做到这一点?
我认为你所寻找的是否定范围,你可以尝试以下方法:
conditions = Contact.group_search('query').where_values @contacts = Contact.where.not(conditions.reduce(:and))
要使此解决方案在Rails 4.x中工作,您应该在作用域中提供值作为数组:
scope :groups, -> { where(contact_type: [2308]) }
我也发现了一个简洁的通用实现来否定范围 ,你也可能会发现它很有趣。