class AtLeastOneValidator < ActiveModel::Validator
def initialize(options)
super
@fields = Array(options.fetch(:fields))
end
def validate(record)
return if @fields.any? { |f| record.public_send(f).present? }
record.errors.add(:base, "Provide at least one of: #{@fields.join(', ')}")
end
end
class SupportRequest < ApplicationRecord
has_one_attached :screenshot
validates_with AtLeastOneValidator, fields: %i[message screenshot]
end
A tiny custom validator keeps complex presence rules out of controllers. This example enforces that at least one of two fields is present (e.g., text content or an attachment).