You could probably do it with one query if you did something like this (off the top of my head, untested):
found_users = User.where("username_lower in (:users) OR email IN (:users)", users: users).pluck(:id, :username_lower, :email)
# convert to hash to make searching faster
found_emails = {}
found_usernames = {}
found_users.each do |fu|
found_emails[fu[1]] = fu[0]
found_usernames[fu[2]] = fu[0]
end
not_found = users.reject? {|u| found_emails[u] || found_usernames[u]}
Then not_found would include all the users inputted that weren’t returned by the SQL query.