模型文件中的 Ruby on Rails IBAN 验证
Posted
技术标签:
【中文标题】模型文件中的 Ruby on Rails IBAN 验证【英文标题】:Ruby on Rails IBAN validation in model file 【发布时间】:2014-12-04 04:07:31 【问题描述】:我正在尝试像任何国家/地区的 iban 代码一样进行 iban 验证。我从 *** 获得了一些帮助来构建该代码,但我仍然有一些问题,我不知道它在哪里。
我总是收到“这不是有效的 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
【问题讨论】:
应该是validate :valid_iban?
和validates :iban, presence: true
两个单独的验证,你应该传递一个方法给validate
。
我刚刚做了。但问题是一样的。我认为它在验证码中
所以你的条件:remainder == 1 && length_correct_for_country
总是被评估为假,然后检查你的逻辑是否正确。
我刚刚阅读了这篇***文章:en.wikipedia.org/wiki/International_Bank_Account_Number您的代码中存在多个问题。例如:您没有检查所有可能的国家/地区代码的长度,或者您生成校验和的代码没有处理所有可能的字符替换。
【参考方案1】:
@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
【讨论】:
【参考方案2】:iban-tools gem 可用于此目的,并且效果很好。
要在 Rails 中使用 gem,我建议编写一个验证器类。
首先把这个放到你的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
【讨论】:
【参考方案3】:你可能需要这样的东西:
validate :valid_iban?
def valid_iban?
end
【讨论】:
我当前的代码是这样的: validate :valid_iban?验证:iban,存在:true 但问题是一样的 可能有问题:letters_removed <<9
应该是letters_removed << 9
也许你应该改变验证代码。有一颗宝石可以进行 iban 检查:link以上是关于模型文件中的 Ruby on Rails IBAN 验证的主要内容,如果未能解决你的问题,请参考以下文章
将重复的SQL模型复制到Ruby on Rails postgresql模型中
如何计算 ruby on rails 中的特定评分计数哈希?