Проверка Ruby on Rails IBAN в файле модели

Я пытаюсь сделать iban-проверку как любой код страны. Я получил некоторую помощь от stackru для сборки этого кода, но все же у меня есть некоторые проблемы, и я не знаю, где это.

Всегда получаю сообщение об ошибке "Это не действительный IBAN". Но иногда я пытался исправить iban-код в соответствии с определенными странами.

Кто-нибудь поможет мне в этом коде для выполнения этой проверки, пожалуйста?

Код здесь:

  class BankAccount < ActiveRecord::Base
  belongs_to :user

  validates :bank_name, presence: true
  validate :iban, :valid_iban?, presence: true

  private

    def valid_iban?
            ibans = iban.upcase.scan(/\w/).join

            ibans = ibans.gsub(/_/, '')

            iban_length = ibans.length

            country = ibans.scan(/\A../).join

            length_correct_for_country = true

            case country
                when "IE"
                    if iban_length == 22
                        length_correct_for_country = true
                    else
                        length_correct_for_country = false      
                    end
                when "AL"
                    if iban_length == 28
                        length_correct_for_country = true
                    else
                        length_correct_for_country = false      
                    end
                when "TR"
                    if iban_length == 26
                        length_correct_for_country = true
                    else
                        length_correct_for_country = false      
                    end
                when "GB"
                    if iban_length == 22
                        length_correct_for_country = true
                    else
                        length_correct_for_country = false      
                    end
                when "VG"
                    if iban_length == 24
                        length_correct_for_country = true
                    else
                        length_correct_for_country = false      
                    end
            end

            first_four_characters = ibans.slice!(0..3)

            reordered_number = ibans + first_four_characters

            letters_removed = []
            reordered_number.scan(/./) do |character|
                case character
                when "A"
                    letters_removed << 10
                when "9"
                    letters_removed <<9
                end
            end

            letters_removed = letters_removed.join.to_i

            remainder = letters_removed % 97

            if remainder == 1 && length_correct_for_country

            else
                remainder = remainder.to_s
                errors.add(:iban, " That is not a valid IBAN. The IBAN that is being supplied")
            end

    end

end

3 ответа

Решение

Для этого доступен гем iban-tools, и он работает очень хорошо.

Чтобы использовать гем в Rails, я рекомендую написать класс валидатора.

Сначала поместите это в свой Gemfile:

gem 'iban-tools'

и беги bundle,

Затем создайте новый каталог app/validators и внутри этого файла с именем iban_validator.rb с этим содержанием:

require 'iban-tools'

class IbanValidator < ActiveModel::Validator
  def validate(record)
    unless IBANTools::IBAN.valid?(record.iban)
      record.errors.add :iban, record.errors.generate_message(:iban, :invalid)
    end
  end
end

В вашем классе модели поместите это:

validates_with IbanValidator

Расширение решения @Joost Baaij.

Чтобы использовать его как любой другой валидатор Rails, вы можете использовать ActiveModel::EachValidator:

      require 'iban-tools'

class IbanValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    return if IBANTools::IBAN.valid?(value)

    record.errors.add attribute, record.errors.generate_message(:attributes, :invalid)
  end
end

Затем вы можете использовать это в своей модели:

      validates bank_number, iban: true

Вам нужно что-то вроде:

validate :valid_iban?

def valid_iban?

end
Другие вопросы по тегам