【发布时间】:2015-07-20 23:11:47
【问题描述】:
我的模型范围有点复杂
class Contact < ActiveRecord::Base
scope :active, -> { 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返回的所有Contactsnot。
但要获得该列表,我必须加载
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 '%' + ? + '%')
有什么办法吗?
【问题讨论】:
-
稍微快一点的方法是:
Contact.where.not(id: Contact.group_search('query').pluck(:id))。仍然是两个查询,但会返回一个关系,并会极大地限制其中一个查询。 AFAIK,没有办法否定范围 atm。 -
是的......查询本身也可能变得非常大......这个表有大约 100k 条记录,并且 ID 是 UUID,所以如果我想要“不(非常common)" 我可能只针对查询字符串查看兆字节。
标签: ruby-on-rails ruby-on-rails-4 activerecord rails-activerecord ruby-on-rails-4.1