I suggest to use does_not_match method and accumulate AND conditions iterating through excluded names. You also don't need call explicitly class name inside the scope, because it is class method
class Participant < ApplicationRecord
scope :exclude_names, ->(*names_to_exclude) {
query = names_to_exclude.reduce(nil) do |q, name|
condition = arel_table[:name_search].does_not_match("%#{name}%")
q&.and(condition) || condition
end
where(query)
}
end
After that you can call this scope
Participant.exclude_names('name1')
# SELECT * FROM participants
# WHERE name_search NOT LIKE '%name1%'
Participant.exclude_names('name1', 'name2')
# SELECT * FROM participants
# WHERE name_search NOT LIKE '%name1%'
# AND name_search NOT LIKE '%name2%'
Participant.exclude_names(%w[name1 name2])
# SELECT * FROM participants
# WHERE name_search NOT LIKE '%name1%'
# AND name_search NOT LIKE '%name2%'
Of course you can use OR like in your question, in this case it will be like this
class Participant < ApplicationRecord
scope :exclude_names, ->(*names_to_exclude) {
query = names_to_exclude.reduce(nil) do |q, name|
condition = arel_table[:name_search].matches("%#{name}%")
q&.or(condition) || condition
end
where.not(query)
}
end
After that you can call this scope, compare with previous queries
Participant.exclude_names('name1')
# SELECT * FROM participants
# WHERE NOT (name_search LIKE '%name1%')
Participant.exclude_names('name1', 'name2')
# SELECT * FROM participants
# WHERE NOT (name_search LIKE '%name1%' OR name_search LIKE '%name2%')
Participant.exclude_names(%w[name1 name2])
# SELECT * FROM participants
# WHERE NOT (name_search LIKE '%name1%' OR name_search LIKE '%name2%')