Skip to content

Instantly share code, notes, and snippets.

@remvee
Created February 5, 2020 11:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remvee/d282d17107f83a267dc2afe8de0d0309 to your computer and use it in GitHub Desktop.
Save remvee/d282d17107f83a267dc2afe8de0d0309 to your computer and use it in GitHub Desktop.
Rails BSN (burgerservicenummer) validator
module BSN
# https://nl.wikipedia.org/wiki/Burgerservicenummer#11-proef
def valid?(val)
num = val.to_s.scan(/\d/).join.to_i
return false if num == 0
digits = ("%09d" % num).split(//).map(&:to_i).reverse
return false unless digits.size == 9
digits[0] = -digits[0]
digits.reduce([]){|m,n| m << (n * (m.size + 1))}.reduce{|m,n| m + n} % 11 == 0
end
module_function :valid?
if defined?(::ActiveRecord)
module ActiveRecordValidations
def validates_bsn_elfproef_of(*attr_names)
attr_names = attr_names.dup
options = attr_names.extract_options!
validate do |record|
attr_names.each do |attr|
next if options[:if] && !options[:if][record]
val = record.public_send(attr)
next if options[:allow_blank] && val.blank?
unless BSN.valid?(val)
record.errors.add(attr, I18n.t('activerecord.errors.messages.bsn_malformed'))
end
end
end
end
end
class ::ActiveRecord::Base
extend BSN::ActiveRecordValidations
end
end
end
if $0 == __FILE__
require 'test/unit'
class BSNTest < Test::Unit::TestCase
def test_valid?
assert_equal true, BSN.valid?('111222333')
assert_equal true, BSN.valid?('123456782')
assert_equal false, BSN.valid?('123456781')
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment