lib/ipaddr_validator.rb
require 'ipaddr'
class IpaddrValidator < ActiveModel::EachValidator
class << self
def valid?(value, options = {})
options = default_options.merge(options)
array =
if options[:array]
return false unless value.is_a?(Array)
value
else
[value]
end
array.all? do |value|
validate_single_ipaddr(value, options)
end
end
def default_options
{ ipv4: true, ipv6: false, array: false }
end
private
def validate_single_ipaddr(value, options)
ip =
if value.is_a?(IPAddr)
value
else
IPAddr.new(value)
end
case
when options[:ipv4] && ip.ipv4?
true
when options[:ipv6] && ip.ipv6?
true
else
false
end
rescue IPAddr::Error
false
end
end
def validate_each(record, attribute, value)
unless self.class.valid?(value, options)
record.errors.add(attribute, options[:message] || :invalid_ipaddr)
end
end
end