外部システムとの連携時によくあるのが、使用できる文字の問題
とある決済系の外部システムとの連携で、使用可能な全角文字は、JISX0208 ( JIS 非漢字 + JIS 第一水準 + JIS 第二水準 ) だけですって書いてあって、しばらく途方に暮れた後、色々と調べて何とか実装できた。
ざっくりいうと、文字コードを、正規表現でチェックするやり方。
サンプルコード
とりあえず、concerns に作成した
app/models/concerns/character_code.rb
module CharacterCode
extend ActiveSupport::Concern
# 使用できる文字は、JISX0208 ( JIS 非漢字 + JIS 第一水準 + JIS 第二水準 )
REGEXP = /\A#{"[ -╂亜-腕弌-熙]".encode("SHIFT_JIS")}+\z/
def self.jisx0208_include?(target_string)
REGEXP.match(target_string.encode("SHIFT_JIS")).present?
rescue Encoding::UndefinedConversionError
false
end
end
場合によっては、半角英数字等も OK の場合もあるので、その場合は、正規表現にそのまま追加
app/models/concerns/character_code.rb
module CharacterCode
extend ActiveSupport::Concern
# 使用できる文字は、半角英数字と JISX0208 ( JIS 非漢字 + JIS 第一水準 + JIS 第二水準 )
REGEXP = /\A#{"[0-9a-zA-Z -╂亜-腕弌-熙]".encode("SHIFT_JIS")}+\z/
def self.jisx0208_include?(target_string)
REGEXP.match(target_string.encode("SHIFT_JIS")).present?
rescue Encoding::UndefinedConversionError
false
end
end
今回は、DBに登録する時点で弾きたかったので、モデルの validate に追加した
app/models/user.rb
class User < ActiveRecord::Base
include CharacterCode
validate :validate_last_name_available, if: -> { last_name.present? }
validate :validate_first_name_available, if: -> { first_name.present? }
private
def validate_last_name_available
errors.add(:last_name, 'に使用できない文字が含まれています') unless CharacterCode.jisx0208_include?(last_name)
end
def validate_first_name_available
errors.add(:first_name, 'に使用できない文字が含まれています') unless CharacterCode.jisx0208_include?(first_name)
end
end
正規表現を修正すれば、カタカナ[ァ-ヶ]
だけとか、ひらがな[ぁ-ん]
だけとかも可能。
使用できる文字は下記で調べた