【问题标题】:rails strip non numeric values before saverails在保存之前去除非数值
【发布时间】:2012-09-20 15:18:51
【问题描述】:

我已经搜索过了,看起来这应该很简单,但我无法让它工作。我试图在保存电话号码之前删除所有非数字字符。这是我目前拥有的:

before_save { |workorder| workorder.phonenumber = 
                  phonenumber.to_s.gsub(/\D/, '').to_i }

所以如果用户输入

925-555-5555

它应该保存 9255555555 但它实际上只保存 925 并忽略之后的所有内容

我也试过了:

before_save { |workorder| workorder.phonenumber = 
                  phonenumber.to_s.gsub(/[^0-9]/, "").to_i }

结果相同。

已解决:

def raw_phonenumber
  self.phonenumber
end
def raw_phonenumber=(s)
  self.phonenumber=s.gsub(/\D/, '')
end

【问题讨论】:

  • 应该是workorder.phonenumber.to_s.gsub(/[^0-9]/, "").to_i ??你错过了workorder(如果那是你的实际代码)
  • phonenumber是什么数据类型?
  • 由于您的数据库表,您的输入被转换为整数:“925-555-5555”.to_i #=> 925

标签: ruby regex ruby-on-rails-3


【解决方案1】:

您当然已将phonenumber 列定义为数字。这就是为什么当您在phonenumber 属性中设置'925-555-5555' 时,它被转换为一个数字,并且只保留925

最好的解决方案是将数据库中的列类型更改为string。创建一个新的迁移:

change_column :table_name, :phonenumber, :string, limit: 30

否则,您可以像这样覆盖设置器以删除非数字字符(但它不会修复以“0”开头的电话号码):

def phonenumber=(phonenumber)
  write_attribute(:phonenumber, phonenumber.gsub(/\D/, ''))
end

更多选择在这个blog post

【讨论】:

  • 我最终根据您的解决方案使用了 getter 和 setter 方法。
  • 也许最好只使用super 而不是write_attribute
  • 根据文档,super 是要走的路。 api.rubyonrails.org/classes/ActiveRecord/…
  • 赞成将电话号码存储为字符串。这不是一个你会做数学运算的数字,而且不存储为字符串会导致比它的价值更多的头痛。
【解决方案2】:

最简单的方法是改变field= 方法:

def field=(value)
  super(value.delete('^0-9'))
end

【讨论】:

    【解决方案3】:

    您可以像这样创建保存/显示手机号码的自定义方法:

    def mobile_number(arg)
    
    if arg.downcase.include?('special chars')
    
    phone_number = arg.downcase.split('special chars')
    
    phone = if phone_number[0].to_i == 0 || phone_number[0].to_i.to_s.size < 10
    number_to_phone(phone_number[0].gsub!(/[^0-9A-Za-z]/, '').to_i, area_code: true)
    else
    number_to_phone(phone_number[0].to_i, area_code: true)
    end
    
    return phone.to_s + ' Ext'+ remove_unnecessary_keywords(phone_number[1])
    
    elsif arg.include?('(') || arg.include?(')') || arg.include?('-') || 
    arg.include?('.') || arg.include?(' ')
    
    return  number_to_phone(arg.gsub!(/[^0-9A-Za-z]/, '').to_i, area_code: true)    
    
    else
    
    return number_to_phone(arg.to_i, area_code: true) 
    
    end
    
    end  
    

    【讨论】:

    • 一般来说,如果答案包含对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-05-28
    • 2014-11-11
    • 1970-01-01
    • 2015-03-08
    • 2013-01-11
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多