Ho un ambito un po 'complicato su un modelloNegate ActiveRecord interrogazione portata
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
A scopo di verifica, voglio fare in modo che tutti Contacts
non restituito da group_search
sono esclusi per i motivi giusti.
Ma per ottenere tale elenco, devo caricare
Contact.all - Contact.group_search('query')
che gestisce due query, restituisce un Array
invece di un Relation
, ed è più lento di quanto mi piacerebbe.
E dal momento che sto testando lo scope group_search
, scrivendo lo un altro scope negativo è il tipo di errore. Preferirei solo fare qualcosa di simile:
Contact.merge.not(Contact.group_search('query'))
per generare la seguente query SQL:
SELECT *
FROM contacts
WHERE NOT (contact_type = 2308 AND inactive = 0 AND last_name LIKE '%' + ? + '%')
C'è un modo di fare questo?
Un modo leggermente più veloce sarebbe: 'Contact.where.not (id: Contact.group_search ('query'). Pluck (: id))'. Ancora due query, ma restituirà una relazione e limiterà drasticamente una delle query. AFAIK, non c'è modo di negare l'ambito atm. – BroiSatse
Sì ... anche la query stessa potrebbe potenzialmente diventare molto grande ... questa tabella ha qualcosa dell'ordine di 100k e gli ID sono UUID, quindi se voglio "non (qualcosa di molto comune)" potrei guardare a megabyte solo per la stringa di query. – PJSCopeland