To undo a scope that you can use:
Contact.where.not(id: Contact.group_search('query'))
This is not the same as using pluck (suggested in one of the comments):
Contact.where.not(id: Contact.group_search('query').pluck(:id))
Without pluck it makes one request (with two choices):
SELECT 'contacts'.* FROM 'contacts' WHERE 'contacts'.'id' NOT IN (SELECT 'contacts'.'id' FROM 'contacts' WHERE 'contacts'.'group_search' = 'query')
Using pluck it makes two independent requests:
SELECT 'contacts'.'id' FROM 'contacts' WHERE 'contacts'.'group_search' = 'query' SELECT 'contacts'.* FROM 'contacts' WHERE 'contacts'.'id' NOT IN (1, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361)
When you request a lot of records, the first one is more efficient. Of course, Contact.where.not(group_search: 'query') more efficient since it produces one query with one select (but in some cases this may not be possible):
SELECT 'contacts'.'id' FROM 'contacts' WHERE 'contacts'.'group_search' != 'query'