Ben test amaçlı olarak bir modelNegate ActiveRecord sorgu kapsamı
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
üzerinde biraz karmaşık kapsamını var, emin olmak için hepsi Contacts
değilgroup_search
doğru nedenlerle dışlanır tarafından döndürülen. o listeyi almak için Ama
, ben
iki sorgu çalıştırırContact.all - Contact.group_search('query')
, yerine Relation
bir Array
döndürür ve İsterdim daha yavaştır yüklemek zorunda.
Ve group_search
kapsamını test ettiğimden, no'lu başka bir kapsamı, negatif olan noktayı bozar. Bunu yapmanın bir yolu
SELECT *
FROM contacts
WHERE NOT (contact_type = 2308 AND inactive = 0 AND last_name LIKE '%' + ? + '%')
var mı:
Contact.merge.not(Contact.group_search('query'))
aşağıdaki SQL sorgusu oluşturmak için: Daha doğrusu bir şey gibi yapardım? Bu çözüm Raylar 4.x çalışmak için, diziler olarak kapsamındaki değerleri sağlamalıdır
conditions = Contact.group_search('query').where_values
@contacts = Contact.where.not(conditions.reduce(:and))
:
Biraz daha hızlı bir şekilde olabilir: 'Contact.where.not (id: Contact.group_search ('query'). Pluck (: id))'. Hala iki sorgu, ancak bir ilişki döndürecek ve sorgulardan birini büyük ölçüde sınırlayacaktır. AFAIK, kapsamı reddetmenin bir yolu yok. – BroiSatse
Evet ... ayrıca sorgunun kendisi de çok büyük olabilir ... bu tablonun 100k kayıt sırasına bir şey var ve ID'leri UUID'ler, yani eğer "istemiyorum (çok yaygın)" Sadece sorgu dizesi için megabaytta. – PJSCopeland