【问题标题】:How do I pass a value from a form for validation如何从表单中传递值以进行验证
【发布时间】:2013-07-24 14:40:41
【问题描述】:

我正在为使用 Ruby on Rails 的直接付款创建一个表单

我已经设置了表单并设置了一些基本验证以确保所有字段都已填写。

接下来我想设置一些验证来检查 IBAN(国际银行帐号)号码是否是有效的 IBAN。

这涉及到处理字符串、将其更改为数字并进行一些数学运算的几个步骤,所有这些我都编写了一个方法。

我的问题是我似乎无法将 IBAN 传递到方法中进行验证。

我的验证:

class DirectDebit < ActiveRecord::Base
attr_accessible :address, :amount, :bank_branch, :bic, :date_for_payment, :email, :iban, :name, :name_of_account, :phone

validates :address, :bank_branch, :bic, :date_for_payment, :email, :name, :name_of_account, :phone, presence: true

validates :amount, numericality: {greater_than_or_equal_to: 0.01}

validate :iban 

def iban

    ## Converts all letters in 'number' to uppercase and removes any spaces and anything else that isn't a letter, number or underscore
    iban = iban.upcase.scan(/\w/).join

    ## removes any underscores as ".scan(/\w/)" above reads in letters digits and underscores.
    iban = iban.gsub(/_/, '')

    ## Calculates the length of 'number'
    iban_length = iban.length

    ## Saves the first two letters in 'number' as 'country'
    country = iban.scan(/\A../).join

    ## Checks if the length is correct for the country
    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 "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

    ## Identifies what the first 4 characters are, and removes them from the rest of the number
    first_four_characters = iban.slice!(0..3)

    ## Adds the first four characters to the end of the rest
    reordered_number = iban + first_four_characters

    ## Set up an array and have each character in the reordered number read into it, changing it to the appropriate number if it is a letter.
    letters_removed = []
    reordered_number.scan(/./) do |character|
        case character
        when "A"
            letters_removed << 10
        ...
        when "9"
            letters_removed <<9
        end
    end

    ## Change the array to a String and then to a number
    letters_removed = letters_removed.join.to_i

    ## Check to see if it gives a remainder of one when divided by 97
    remainder = letters_removed % 97

    ## Output that it is a valid number if the remainder when it is divided by 97 is 1 and if it is the correct length for the country.
    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 is: " + special)
    end

end

end

【问题讨论】:

  • 在第一行尝试iban = self.iban.upcase.scan(/\w/).join。此外,如果您不确定使用调试器的值是什么,或者只是输入Rails.logger.info "*"*50; Rails.logger.info [:iban_after_smth, iban].inspect

标签: ruby-on-rails forms


【解决方案1】:

在您的模型中,iban 已经是一种方法,因为它是一个数据库列。因此,您需要执行以下操作:

validate :valid_iban?

def valid_iban?
  ## all of your current validation iban goes here
end

如果您希望能够验证模型的 iban 和可能的其他 iban:

app/models/validates_iban.rb

class ValidatesIban
  def self.valid?(iban)
    ## all your validation goes here
  end
end

在你的模型中:

validate :valid_iban?

def valid_iban?
  unless ValidatesIban.valid?(iban)
    self.errors(:iban, "is not valid")
  end
end

ValidatesIban 方法的优点:您可以在其他地方重复使用。

【讨论】:

  • 谢谢,一旦我对 ValidatesIban 方法进行了一些操作,它就奏效了。
【解决方案2】:

我想这个已经很好了,但我想添加更多选项:

  1. 您可以使用 gem 'iban-tools',https://github.com/iulianu/iban-tools
  2. 另外,对于 (SEPA) 直接借记表格/协议,试试这个 sepa_king gem,它还验证 BIC 和债权人标识符(您可以看到,在 IBAN 内部,它也使用 iban-tools,https://github.com/salesking/sepa_king/blob/master/lib/sepa_king/validator.rb

干杯!

【讨论】:

    【解决方案3】:

    试试这个:

    class YourModel < ActiveRecord::Base
    
      validate :your_method
    
    
      def your_method
        #your stuff should return true or false        
      end
    
    end
    

    希望它会有所帮助。

    【讨论】:

    • 这是我所拥有的基本版本。
    • 完成了,有两个长的重复部分,我已经从中间剪掉了,并用刚刚读到的行替换...
    • 返回真或假不是问题,没有任何东西被传入进行测试,因此我每次都有效地得到假,除非我硬编码一个将验证为真的 IBAN。
    • 将您的方法名称更改为其他名称。
    猜你喜欢
    • 2021-03-10
    • 2016-08-27
    • 2018-02-05
    • 1970-01-01
    • 2020-01-27
    • 2014-08-15
    • 2011-04-18
    • 2014-08-04
    • 2017-11-28
    相关资源
    最近更新 更多