Tôi có một phạm vi hơi phức tạp trên một mô hìnhphủ nhận ActiveRecord phạm vi truy vấn
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
Đối với mục đích thử nghiệm, tôi muốn chắc chắn rằng tất cả Contacts
không trả về bởi group_search
bị loại trừ vì những lý do đúng đắn.
Nhưng để có được danh sách đó, tôi phải nạp
Contact.all - Contact.group_search('query')
chạy hai truy vấn, trả về một Array
thay vì một Relation
, và là chậm hơn so với tôi muốn.
Và vì tôi đang thử nghiệm phạm vi group_search
, hãy viết một phạm vi khác là tiêu cực của nó sẽ làm hỏng điểm. Tôi chỉ muốn làm một cái gì đó như:
Contact.merge.not(Contact.group_search('query'))
để tạo ra các truy vấn SQL sau:
SELECT *
FROM contacts
WHERE NOT (contact_type = 2308 AND inactive = 0 AND last_name LIKE '%' + ? + '%')
Có cách nào để làm điều này?
Cách nhanh hơn một chút sẽ là: 'Contact.where.not (id: Contact.group_search ('query'). Pluck (: id))'. Vẫn còn hai truy vấn, nhưng sẽ trả về một mối quan hệ và sẽ hạn chế đáng kể một trong các truy vấn. AFAIK, không có cách nào để phủ nhận phạm vi atm. – BroiSatse
Vâng ... bản thân truy vấn cũng có khả năng nhận được rất lớn ... bảng này có thứ gì đó với thứ tự 100 nghìn bản ghi và ID là UUID, vì vậy nếu tôi muốn "không (cái gì đó rất phổ biến)", tôi có thể tìm kiếm ở megabyte chỉ dành cho chuỗi truy vấn. – PJSCopeland