Edited at

小文字/大文字や単数/複数形も含めてexclusionチェックするCustomValidator

More than 1 year has passed since last update.

ユーザー名などのバリデーションに、予約語リストを作って対処していたのですが、ケースセンシティブだったり、単数・複数を個別に書くのが大変だったので、CustomValidatorを作ってみました。


exclusionを使った場合


/app/models/user.rb

validates :title,

exclusion: { in: YAML.safe_load(open("#{Rails.root}/config/exclusion/username.yml", &:read)) }


/config/exclusion/username.yml

# 予約語リスト

- user
- users
- manager
- managers

この場合、単数形・複数形は、自力で書いてるのでいいのですが、大文字小文字まで自力でやるわけには行きません…。


CustomValidatorを使った場合

カスタムバリデータークラスを作成します。


/app/validators/exclusion_extend_validator.rb

# coding: utf-8

# frozen_string_literal: true
# 通常のexclusionに追加で、小文字単数形にしてチェックをする
class ExclusionExtendValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return unless value.present?

list = options[:in]
# 含まれていたらエラー
if list.include?(value)
record.errors.add(attribute, 'is reserved')
# 小文字、単数形に変換して再度チェック
elsif list.include?(value.try(:downcase).try(:singularize))
record.errors.add(attribute, 'is reserved')
end
end
end


上記ファイルを読み込むように、下記追加します。


/config/application.rb

config.autoload_paths += Dir["#{config.root}/app/validators"]


exclusion:のときと同じように、使います。


/app/models/user.rb

validates :title,

exclusion_extend: { in: YAML.safe_load(open("#{Rails.root}/config/exclusion/username.yml", &:read)) }

大文字/小文字や、単数形/複数形も含めてチェックされるようになります。

※ yamlファイルには、小文字・単数形で書くようにします。


/config/exclusion/username.yml

# 予約語リスト(小文字・単数形)

- user
- manager

これでuserusersUserUSERSなども弾かれるようになります。